1 /* src/vm/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.hpp"
42 #include "threads/mutex.hpp"
44 #include "toolbox/logging.h"
46 #include "vm/array.hpp"
47 #include "vm/jit/builtin.hpp"
49 #include "vm/classcache.h"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/jit/jitcache.hpp"
55 #include "vm/linker.h"
56 #include "vm/loader.hpp"
57 #include "vm/options.h"
58 #include "vm/resolve.h"
60 #if defined(ENABLE_STATISTICS)
61 # include "vm/statistics.h"
64 #include "vm/suck.hpp"
67 #include "vm/jit/asmpart.h"
70 /* class_set_packagename *******************************************************
72 Derive the package name from the class name and store it in the
75 An internal package name consists of the package name plus the
76 trailing '/', e.g. "java/lang/".
78 For classes in the unnamed package, the package name is set to
81 *******************************************************************************/
83 void class_set_packagename(classinfo *c)
88 p = UTF_END(c->name) - 1;
89 start = c->name->text;
91 if (c->name->text[0] == '[') {
92 /* Set packagename of arrays to the element's package. */
94 for (; *start == '['; start++);
96 /* Skip the 'L' in arrays of references. */
102 /* Search for last '/'. */
104 for (; (p > start) && (*p != '/'); --p);
106 /* If we found a '/' we set the package name plus the trailing
107 '/'. Otherwise we set the packagename to NULL. */
110 c->packagename = utf_new(start, p - start + 1);
112 c->packagename = NULL;
116 /* class_create_classinfo ******************************************************
118 Create a new classinfo struct. The class name is set to the given utf *,
119 most other fields are initialized to zero.
121 Note: classname may be NULL. In this case a not-yet-named classinfo is
122 created. The name must be filled in later and class_set_packagename
123 must be called after that.
125 *******************************************************************************/
127 classinfo *class_create_classinfo(utf *classname)
131 #if defined(ENABLE_STATISTICS)
133 size_classinfo += sizeof(classinfo);
136 /* we use a safe name for temporarily unnamed classes */
138 if (classname == NULL)
139 classname = utf_not_named_yet;
143 log_message_utf("Creating class: ", classname);
146 #if !defined(ENABLE_GC_BOEHM)
147 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
148 /*c = NEW(classinfo);
149 MZERO(c, classinfo, 1);*/
151 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
152 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
157 /* Set the header.vftbl of all loaded classes to the one of
158 java.lang.Class, so Java code can use a class as object. */
160 if (class_java_lang_Class != NULL)
161 if (class_java_lang_Class->vftbl != NULL)
162 c->object.header.vftbl = class_java_lang_Class->vftbl;
164 #if defined(ENABLE_JAVASE)
165 /* check if the class is a reference class and flag it */
167 if (classname == utf_java_lang_ref_SoftReference) {
168 c->flags |= ACC_CLASS_REFERENCE_SOFT;
170 else if (classname == utf_java_lang_ref_WeakReference) {
171 c->flags |= ACC_CLASS_REFERENCE_WEAK;
173 else if (classname == utf_java_lang_ref_PhantomReference) {
174 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
178 if (classname != utf_not_named_yet)
179 class_set_packagename(c);
180 #if defined (ENABLE_JITCACHE)
181 c->cache_file_fd = 0;
184 Lockword_init(&(c->object.header.lockword));
190 /* class_postset_header_vftbl **************************************************
192 Set the header.vftbl of all classes created before java.lang.Class
193 was linked. This is necessary that Java code can use a class as
196 *******************************************************************************/
198 void class_postset_header_vftbl(void)
202 classcache_name_entry *nmen;
203 classcache_class_entry *clsen;
205 assert(class_java_lang_Class);
207 for (slot = 0; slot < hashtable_classcache.size; slot++) {
208 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
210 for (; nmen; nmen = nmen->hashlink) {
211 /* iterate over all class entries */
213 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
216 /* now set the the vftbl */
218 if (c->object.header.vftbl == NULL)
219 c->object.header.vftbl = class_java_lang_Class->vftbl;
225 /* class_define ****************************************************************
227 Calls the loader and defines a class in the VM.
229 *******************************************************************************/
231 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
238 /* check if this class has already been defined */
240 c = classcache_lookup_defined_or_initiated(cl, name);
243 exceptions_throw_linkageerror("duplicate class definition: ", c);
248 /* create a new classinfo struct */
250 c = class_create_classinfo(name);
252 #if defined(ENABLE_STATISTICS)
255 if (opt_getloadingtime)
259 /* build a classbuffer with the given data */
261 cb = NEW(classbuffer);
268 /* preset the defining classloader */
272 /* load the class from this buffer */
274 r = load_class_from_classbuffer(cb);
278 FREE(cb, classbuffer);
280 #if defined(ENABLE_STATISTICS)
283 if (opt_getloadingtime)
288 /* If return value is NULL, we had a problem and the class is
289 not loaded. Now free the allocated memory, otherwise we
290 could run into a DOS. */
297 #if defined(ENABLE_JAVASE)
298 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
299 /* Store the protection domain. */
301 c->protectiondomain = pd;
305 /* Store the newly defined class in the class cache. This call
306 also checks whether a class of the same name has already been
307 defined by the same defining loader, and if so, replaces the
308 newly created class by the one defined earlier. */
310 /* Important: The classinfo given to classcache_store must be
311 fully prepared because another thread may return
312 this pointer after the lookup at to top of this
313 function directly after the class cache lock has
316 c = classcache_store(cl, c, true);
322 /* class_load_attribute_sourcefile *********************************************
324 SourceFile_attribute {
325 u2 attribute_name_index;
330 *******************************************************************************/
332 static bool class_load_attribute_sourcefile(classbuffer *cb)
343 /* check buffer size */
345 if (!suck_check_classbuffer_size(cb, 4 + 2))
348 /* check attribute length */
350 attribute_length = suck_u4(cb);
352 if (attribute_length != 2) {
353 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
357 /* there can be no more than one SourceFile attribute */
359 if (c->sourcefile != NULL) {
360 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
366 sourcefile_index = suck_u2(cb);
367 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
369 if (sourcefile == NULL)
372 /* store sourcefile */
374 c->sourcefile = sourcefile;
380 /* class_load_attribute_enclosingmethod ****************************************
382 EnclosingMethod_attribute {
383 u2 attribute_name_index;
389 *******************************************************************************/
391 #if defined(ENABLE_JAVASE)
392 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
398 classref_or_classinfo cr;
399 constant_nameandtype *cn;
405 /* check buffer size */
407 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
410 /* check attribute length */
412 attribute_length = suck_u4(cb);
414 if (attribute_length != 4) {
415 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
419 /* there can be no more than one EnclosingMethod attribute */
421 if (c->enclosingmethod != NULL) {
422 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
426 /* get class index */
428 class_index = suck_u2(cb);
429 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
431 /* get method index */
433 method_index = suck_u2(cb);
434 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
436 /* store info in classinfo */
438 c->enclosingclass.any = cr.any;
439 c->enclosingmethod = cn;
443 #endif /* defined(ENABLE_JAVASE) */
446 /* class_load_attributes *******************************************************
448 Read attributes from ClassFile.
451 u2 attribute_name_index;
453 u1 info[attribute_length];
456 InnerClasses_attribute {
457 u2 attribute_name_index;
461 *******************************************************************************/
463 bool class_load_attributes(classbuffer *cb)
466 uint16_t attributes_count;
467 uint16_t attribute_name_index;
469 innerclassinfo *info;
470 classref_or_classinfo inner;
471 classref_or_classinfo outer;
478 /* get attributes count */
480 if (!suck_check_classbuffer_size(cb, 2))
483 attributes_count = suck_u2(cb);
485 for (i = 0; i < attributes_count; i++) {
486 /* get attribute name */
488 if (!suck_check_classbuffer_size(cb, 2))
491 attribute_name_index = suck_u2(cb);
493 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
495 if (attribute_name == NULL)
498 if (attribute_name == utf_InnerClasses) {
501 if (c->innerclass != NULL) {
502 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
506 if (!suck_check_classbuffer_size(cb, 4 + 2))
509 /* skip attribute length */
512 /* number of records */
513 c->innerclasscount = suck_u2(cb);
515 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
518 /* allocate memory for innerclass structure */
519 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
521 for (j = 0; j < c->innerclasscount; j++) {
522 /* The innerclass structure contains a class with an encoded
523 name, its defining scope, its simple name and a bitmask of
526 info = c->innerclass + j;
528 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
529 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
530 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
533 /* If the current inner-class is the currently loaded
534 class check for some special flags. */
536 if (inner.ref->name == c->name) {
537 /* If an inner-class is not a member, its
538 outer-class is NULL. */
540 if (outer.ref != NULL) {
541 c->flags |= ACC_CLASS_MEMBER;
543 /* A member class doesn't have an
544 EnclosingMethod attribute, so set the
545 enclosing-class to be the same as the
548 c->declaringclass = outer;
549 c->enclosingclass = outer;
552 /* If an inner-class is anonymous, its name is
556 c->flags |= ACC_CLASS_ANONYMOUS;
559 info->inner_class = inner;
560 info->outer_class = outer;
565 else if (attribute_name == utf_SourceFile) {
568 if (!class_load_attribute_sourcefile(cb))
571 #if defined(ENABLE_JAVASE)
572 else if (attribute_name == utf_EnclosingMethod) {
573 /* EnclosingMethod */
575 if (!class_load_attribute_enclosingmethod(cb))
578 else if (attribute_name == utf_Signature) {
581 if (!loader_load_attribute_signature(cb, &(c->signature)))
586 #if defined(ENABLE_ANNOTATIONS)
587 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
588 /* RuntimeVisibleAnnotations */
589 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
592 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
593 /* RuntimeInvisibleAnnotations */
594 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
600 /* unknown attribute */
602 if (!loader_skip_attribute_body(cb))
611 /* class_freepool **************************************************************
613 Frees all resources used by this classes Constant Pool.
615 *******************************************************************************/
617 static void class_freecpool(classinfo *c)
623 if (c->cptags && c->cpinfos) {
624 for (idx = 0; idx < c->cpcount; idx++) {
625 tag = c->cptags[idx];
626 info = c->cpinfos[idx];
630 case CONSTANT_Fieldref:
631 case CONSTANT_Methodref:
632 case CONSTANT_InterfaceMethodref:
633 FREE(info, constant_FMIref);
635 case CONSTANT_Integer:
636 FREE(info, constant_integer);
639 FREE(info, constant_float);
642 FREE(info, constant_long);
644 case CONSTANT_Double:
645 FREE(info, constant_double);
647 case CONSTANT_NameAndType:
648 FREE(info, constant_nameandtype);
656 MFREE(c->cptags, u1, c->cpcount);
659 MFREE(c->cpinfos, void*, c->cpcount);
663 /* class_getconstant ***********************************************************
665 Retrieves the value at position 'pos' of the constantpool of a
666 class. If the type of the value is other than 'ctype', an error is
669 *******************************************************************************/
671 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
673 /* check index and type of constantpool entry */
674 /* (pos == 0 is caught by type comparison) */
676 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
677 exceptions_throw_classformaterror(c, "Illegal constant pool index");
681 return c->cpinfos[pos];
685 /* innerclass_getconstant ******************************************************
687 Like class_getconstant, but if cptags is ZERO, null is returned.
689 *******************************************************************************/
691 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
693 /* invalid position in constantpool */
695 if (pos >= c->cpcount) {
696 exceptions_throw_classformaterror(c, "Illegal constant pool index");
700 /* constantpool entry of type 0 */
702 if (c->cptags[pos] == 0)
705 /* check type of constantpool entry */
707 if (c->cptags[pos] != ctype) {
708 exceptions_throw_classformaterror(c, "Illegal constant pool index");
712 return c->cpinfos[pos];
716 /* class_free ******************************************************************
718 Frees all resources used by the class.
720 *******************************************************************************/
722 void class_free(classinfo *c)
727 #if defined(ENABLE_JITCACHE)
728 /* TODO: Find a way around the linker problem */
729 /* jitcache_freeclass(c);*/
734 if (c->interfaces != NULL)
735 MFREE(c->interfaces, classinfo*, c->interfacescount);
738 for (i = 0; i < c->fieldscount; i++)
739 field_free(&(c->fields[i]));
740 MFREE(c->fields, fieldinfo, c->fieldscount);
744 for (i = 0; i < c->methodscount; i++)
745 method_free(&(c->methods[i]));
746 MFREE(c->methods, methodinfo, c->methodscount);
749 if ((v = c->vftbl) != NULL) {
751 mem_free(v->arraydesc,sizeof(arraydescriptor));
753 for (i = 0; i < v->interfacetablelength; i++) {
754 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
756 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
758 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
759 sizeof(methodptr*) * (v->interfacetablelength -
760 (v->interfacetablelength > 0));
761 v = (vftbl_t*) (((methodptr*) v) -
762 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
767 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
769 /* if (c->classvftbl)
770 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
776 /* get_array_class *************************************************************
778 Returns the array class with the given name for the given
779 classloader, or NULL if an exception occurred.
781 Note: This function does eager loading.
783 *******************************************************************************/
785 static classinfo *get_array_class(utf *name,classloader_t *initloader,
786 classloader_t *defloader,bool link)
790 /* lookup this class in the classcache */
791 c = classcache_lookup(initloader,name);
793 c = classcache_lookup_defined(defloader,name);
796 /* we have to create it */
797 c = class_create_classinfo(name);
798 c = load_newly_created_array(c,initloader);
804 assert(c->state & CLASS_LOADED);
805 assert(c->classloader == defloader);
807 if (link && !(c->state & CLASS_LINKED))
811 assert(!link || (c->state & CLASS_LINKED));
817 /* class_array_of **************************************************************
819 Returns an array class with the given component class. The array
820 class is dynamically created if neccessary.
822 *******************************************************************************/
824 classinfo *class_array_of(classinfo *component, bool link)
832 cl = component->classloader;
834 /* Assemble the array class name */
835 namelen = component->name->blength;
837 if (component->name->text[0] == '[') {
838 /* the component is itself an array */
839 namebuf = MNEW(char, namelen + 1);
841 MCOPY(namebuf + 1, component->name->text, char, namelen);
845 /* the component is a non-array class */
846 namebuf = MNEW(char, namelen + 3);
849 MCOPY(namebuf + 2, component->name->text, char, namelen);
850 namebuf[2 + namelen] = ';';
854 u = utf_new(namebuf, namelen);
856 MFREE(namebuf, char, namelen);
858 c = get_array_class(u, cl, cl, link);
864 /* class_multiarray_of *********************************************************
866 Returns an array class with the given dimension and element class.
867 The array class is dynamically created if neccessary.
869 *******************************************************************************/
871 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
878 log_text("Invalid array dimension requested");
882 /* Assemble the array class name */
883 namelen = element->name->blength;
885 if (element->name->text[0] == '[') {
886 /* the element is itself an array */
887 namebuf = MNEW(char, namelen + dim);
888 memcpy(namebuf + dim, element->name->text, namelen);
892 /* the element is a non-array class */
893 namebuf = MNEW(char, namelen + 2 + dim);
895 memcpy(namebuf + dim + 1, element->name->text, namelen);
896 namelen += (2 + dim);
897 namebuf[namelen - 1] = ';';
899 memset(namebuf, '[', dim);
901 utf* u = utf_new(namebuf, namelen);
903 MFREE(namebuf, char, namelen);
905 c = get_array_class(u,
906 element->classloader,
907 element->classloader,
914 /* class_lookup_classref *******************************************************
916 Looks up the constant_classref for a given classname in the classref
920 cls..............the class containing the reference
921 name.............the name of the class refered to
924 a pointer to a constant_classref, or
925 NULL if the reference was not found
927 *******************************************************************************/
929 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
931 constant_classref *ref;
932 extra_classref *xref;
937 assert(!cls->classrefcount || cls->classrefs);
939 /* first search the main classref table */
940 count = cls->classrefcount;
941 ref = cls->classrefs;
942 for (; count; --count, ++ref)
943 if (ref->name == name)
946 /* next try the list of extra classrefs */
947 for (xref = cls->extclassrefs; xref; xref = xref->next) {
948 if (xref->classref.name == name)
949 return &(xref->classref);
957 /* class_get_classref **********************************************************
959 Returns the constant_classref for a given classname.
962 cls..............the class containing the reference
963 name.............the name of the class refered to
966 a pointer to a constant_classref (never NULL)
969 The given name is not checked for validity!
971 *******************************************************************************/
973 constant_classref *class_get_classref(classinfo *cls, utf *name)
975 constant_classref *ref;
976 extra_classref *xref;
981 ref = class_lookup_classref(cls,name);
985 xref = NEW(extra_classref);
986 CLASSREF_INIT(xref->classref,cls,name);
988 xref->next = cls->extclassrefs;
989 cls->extclassrefs = xref;
991 return &(xref->classref);
995 /* class_get_self_classref *****************************************************
997 Returns the constant_classref to the class itself.
1000 cls..............the class containing the reference
1003 a pointer to a constant_classref (never NULL)
1005 *******************************************************************************/
1007 constant_classref *class_get_self_classref(classinfo *cls)
1009 /* XXX this should be done in a faster way. Maybe always make */
1010 /* the classref of index 0 a self reference. */
1011 return class_get_classref(cls,cls->name);
1014 /* class_get_classref_multiarray_of ********************************************
1016 Returns an array type reference with the given dimension and element class
1020 dim..............the requested dimension
1021 dim must be in [1;255]. This is NOT checked!
1022 ref..............the component class reference
1025 a pointer to the class reference for the array type
1028 The referer of `ref` is used as the referer for the new classref.
1030 *******************************************************************************/
1032 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1036 constant_classref *cr;
1039 assert(dim >= 1 && dim <= 255);
1041 /* Assemble the array class name */
1042 namelen = ref->name->blength;
1044 if (ref->name->text[0] == '[') {
1045 /* the element is itself an array */
1046 namebuf = MNEW(char, namelen + dim);
1047 memcpy(namebuf + dim, ref->name->text, namelen);
1051 /* the element is a non-array class */
1052 namebuf = MNEW(char, namelen + 2 + dim);
1054 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1055 namelen += (2 + dim);
1056 namebuf[namelen - 1] = ';';
1058 memset(namebuf, '[', dim);
1060 utf* u = utf_new(namebuf, namelen);
1062 MFREE(namebuf, char, namelen);
1064 cr = class_get_classref(ref->referer, u);
1070 /* class_get_classref_component_of *********************************************
1072 Returns the component classref of a given array type reference
1075 ref..............the array type reference
1078 a reference to the component class, or
1079 NULL if `ref` is not an object array type reference
1082 The referer of `ref` is used as the referer for the new classref.
1084 *******************************************************************************/
1086 constant_classref *class_get_classref_component_of(constant_classref *ref)
1093 name = ref->name->text;
1097 namelen = ref->name->blength - 1;
1102 else if (*name != '[') {
1106 return class_get_classref(ref->referer, utf_new(name, namelen));
1110 /* class_findmethod ************************************************************
1112 Searches a 'classinfo' structure for a method having the given name
1113 and descriptor. If descriptor is NULL, it is ignored.
1115 *******************************************************************************/
1117 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1122 for (i = 0; i < c->methodscount; i++) {
1123 m = &(c->methods[i]);
1125 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1133 /* class_resolvemethod *********************************************************
1135 Searches a class and it's super classes for a method.
1137 Superinterfaces are *not* searched.
1139 *******************************************************************************/
1141 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1146 m = class_findmethod(c, name, desc);
1151 /* JVM Specification bug:
1153 It is important NOT to resolve special <init> and <clinit>
1154 methods to super classes or interfaces; yet, this is not
1155 explicited in the specification. Section 5.4.3.3 should be
1156 updated appropriately. */
1158 if (name == utf_init || name == utf_clinit)
1168 /* class_resolveinterfacemethod_intern *****************************************
1170 Internally used helper function. Do not use this directly.
1172 *******************************************************************************/
1174 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1175 utf *name, utf *desc)
1180 /* try to find the method in the class */
1182 m = class_findmethod(c, name, desc);
1187 /* No method found? Try the super interfaces. */
1189 for (i = 0; i < c->interfacescount; i++) {
1190 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1196 /* no method found */
1202 /* class_resolveclassmethod ****************************************************
1204 Resolves a reference from REFERER to a method with NAME and DESC in
1207 If the method cannot be resolved the return value is NULL. If
1208 EXCEPT is true *exceptionptr is set, too.
1210 *******************************************************************************/
1212 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1213 classinfo *referer, bool throwexception)
1219 /* if (c->flags & ACC_INTERFACE) { */
1220 /* if (throwexception) */
1221 /* *exceptionptr = */
1222 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1226 /* try class c and its superclasses */
1230 m = class_resolvemethod(cls, name, desc);
1235 /* Try the super interfaces. */
1237 for (i = 0; i < c->interfacescount; i++) {
1238 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1245 exceptions_throw_nosuchmethoderror(c, name, desc);
1250 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1252 exceptions_throw_abstractmethoderror();
1257 /* XXX check access rights */
1263 /* class_resolveinterfacemethod ************************************************
1265 Resolves a reference from REFERER to a method with NAME and DESC in
1268 If the method cannot be resolved the return value is NULL. If
1269 EXCEPT is true *exceptionptr is set, too.
1271 *******************************************************************************/
1273 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1274 classinfo *referer, bool throwexception)
1278 if (!(c->flags & ACC_INTERFACE)) {
1280 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1285 mi = class_resolveinterfacemethod_intern(c, name, desc);
1290 /* try class java.lang.Object */
1292 mi = class_findmethod(class_java_lang_Object, name, desc);
1298 exceptions_throw_nosuchmethoderror(c, name, desc);
1304 /* class_findfield *************************************************************
1306 Searches for field with specified name and type in a classinfo
1307 structure. If no such field is found NULL is returned.
1309 *******************************************************************************/
1311 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1315 for (i = 0; i < c->fieldscount; i++)
1316 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1317 return &(c->fields[i]);
1319 if (c->super != NULL)
1320 return class_findfield(c->super, name, desc);
1326 /* class_findfield_approx ******************************************************
1328 Searches in 'classinfo'-structure for a field with the specified
1331 *******************************************************************************/
1333 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1335 for (int32_t i = 0; i < c->fieldscount; i++) {
1336 fieldinfo* f = &(c->fields[i]);
1338 if (f->name == name)
1343 exceptions_throw_nosuchfielderror(c, name);
1348 /****************** Function: class_resolvefield_int ***************************
1350 This is an internally used helper function. Do not use this directly.
1352 Tries to resolve a field having the given name and type.
1353 If the field cannot be resolved, NULL is returned.
1355 *******************************************************************************/
1357 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1362 /* search for field in class c */
1364 for (i = 0; i < c->fieldscount; i++) {
1365 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1366 return &(c->fields[i]);
1370 /* Try super interfaces recursively. */
1372 for (i = 0; i < c->interfacescount; i++) {
1373 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1379 /* Try super class. */
1381 if (c->super != NULL)
1382 return class_resolvefield_int(c->super, name, desc);
1390 /********************* Function: class_resolvefield ***************************
1392 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1394 If the field cannot be resolved, an exception is thrown and the
1395 return value is NULL.
1397 *******************************************************************************/
1399 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1403 fi = class_resolvefield_int(c, name, desc);
1406 exceptions_throw_nosuchfielderror(c, name);
1410 /* XXX check access rights */
1416 /* class_issubclass ************************************************************
1418 Checks if sub is a descendant of super.
1420 *******************************************************************************/
1422 bool class_issubclass(classinfo *sub, classinfo *super)
1429 /* We reached java/lang/Object and did not find the requested
1435 /* We found the requested super class. */
1445 /* class_isanysubclass *********************************************************
1447 Checks a subclass relation between two classes. Implemented
1448 interfaces are interpreted as super classes.
1450 Return value: 1 ... sub is subclass of super
1453 *******************************************************************************/
1455 bool class_isanysubclass(classinfo *sub, classinfo *super)
1460 /* This is the trivial case. */
1465 /* Primitive classes are only subclasses of themselves. */
1467 if (class_is_primitive(sub) || class_is_primitive(super))
1470 /* Check for interfaces. */
1472 if (super->flags & ACC_INTERFACE) {
1473 result = (sub->vftbl->interfacetablelength > super->index) &&
1474 (sub->vftbl->interfacetable[-super->index] != NULL);
1477 /* java.lang.Object is the only super class of any
1480 if (sub->flags & ACC_INTERFACE)
1481 return (super == class_java_lang_Object);
1483 Mutex_lock(linker_classrenumber_mutex);
1485 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1486 result = diffval <= (uint32_t) super->vftbl->diffval;
1488 Mutex_unlock(linker_classrenumber_mutex);
1495 /* class_is_assignable_from ****************************************************
1497 Return whether an instance of the "from" class parameter would be
1498 an instance of this class "to" as well.
1505 true .... is assignable
1506 false ... is not assignable
1508 *******************************************************************************/
1510 bool class_is_assignable_from(classinfo *to, classinfo *from)
1512 if (!(to->state & CLASS_LINKED))
1513 if (!link_class(to))
1516 if (!(from->state & CLASS_LINKED))
1517 if (!link_class(from))
1520 return class_isanysubclass(from, to);
1524 /* class_is_instance ***********************************************************
1526 Return if the given Java object is an instance of the given class.
1533 true .... is instance
1534 false ... is not instance
1536 *******************************************************************************/
1538 bool class_is_instance(classinfo *c, java_handle_t *h)
1540 if (!(c->state & CLASS_LINKED))
1544 return builtin_instanceof(h, c);
1548 /* class_get_componenttype *****************************************************
1550 Return the component class of the given class. If the given class
1551 is not an array, return NULL.
1553 *******************************************************************************/
1555 classinfo *class_get_componenttype(classinfo *c)
1557 classinfo *component;
1558 arraydescriptor *ad;
1560 /* XXX maybe we could find a way to do this without linking. */
1561 /* This way should be safe and easy, however. */
1563 if (!(c->state & CLASS_LINKED))
1567 ad = c->vftbl->arraydesc;
1572 if (ad->arraytype == ARRAYTYPE_OBJECT)
1573 component = ad->componentvftbl->clazz;
1575 component = Primitive_get_class_by_type(ad->arraytype);
1581 /* class_get_declaredclasses ***************************************************
1583 Return an array of declared classes of the given class.
1585 *******************************************************************************/
1587 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1589 classref_or_classinfo inner;
1590 classref_or_classinfo outer;
1592 int declaredclasscount; /* number of declared classes */
1593 int pos; /* current declared class */
1594 java_handle_objectarray_t *oa; /* array of declared classes */
1598 declaredclasscount = 0;
1600 if (!class_is_primitive(c) && !class_is_array(c)) {
1601 /* Determine number of declared classes. */
1603 for (i = 0; i < c->innerclasscount; i++) {
1604 /* Get outer-class. If the inner-class is not a member
1605 class, the outer-class is NULL. */
1607 outer = c->innerclass[i].outer_class;
1609 if (outer.any == NULL)
1612 /* Check if outer-class is a classref or a real class and
1613 get the class name from the structure. */
1615 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1617 /* Outer class is this class. */
1619 if ((outername == c->name) &&
1620 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1621 declaredclasscount++;
1625 /* Allocate Class[] and check for OOM. */
1627 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1632 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1633 inner = c->innerclass[i].inner_class;
1634 outer = c->innerclass[i].outer_class;
1636 /* Get outer-class. If the inner-class is not a member class,
1637 the outer-class is NULL. */
1639 if (outer.any == NULL)
1642 /* Check if outer_class is a classref or a real class and get
1643 the class name from the structure. */
1645 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1647 /* Outer class is this class. */
1649 if ((outername == c->name) &&
1650 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1652 ic = resolve_classref_or_classinfo_eager(inner, false);
1657 if (!(ic->state & CLASS_LINKED))
1658 if (!link_class(ic))
1661 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1670 * Return an array of declared constructors of the given class.
1672 * @param c class to get the constructors of
1673 * @param publicOnly show only public fields
1675 * @return array of java.lang.reflect.Constructor
1677 #if defined(ENABLE_JAVASE)
1678 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1681 java_handle_objectarray_t* oa;
1687 /* Determine number of constructors. */
1691 for (i = 0; i < c->methodscount; i++) {
1692 m = &(c->methods[i]);
1694 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1695 (m->name == utf_init))
1699 /* Create array of constructors. */
1701 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1706 /* Get the constructors and store them in the array. */
1708 for (i = 0, index = 0; i < c->methodscount; i++) {
1709 m = &(c->methods[i]);
1711 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1712 (m->name == utf_init)) {
1713 // Create a java.lang.reflect.Constructor object.
1715 rc = java_lang_reflect_Constructor_create(m);
1717 /* Store object into array. */
1719 array_objectarray_element_set(oa, index, rc);
1729 /* class_get_declaredfields ****************************************************
1731 Return an array of declared fields of the given class.
1734 c ............ class to get the fields of
1735 publicOnly ... show only public fields
1738 array of java.lang.reflect.Field
1740 *******************************************************************************/
1742 #if defined(ENABLE_JAVASE)
1743 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1745 java_handle_objectarray_t *oa;
1752 /* Determine number of fields. */
1756 for (i = 0; i < c->fieldscount; i++)
1757 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1760 /* Create array of fields. */
1762 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1767 /* Get the fields and store them in the array. */
1769 for (i = 0, index = 0; i < c->fieldscount; i++) {
1770 f = &(c->fields[i]);
1772 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1773 // Create a java.lang.reflect.Field object.
1775 h = java_lang_reflect_Field_create(f);
1777 /* Store object into array. */
1779 array_objectarray_element_set(oa, index, h);
1789 /* class_get_declaredmethods ***************************************************
1791 Return an array of declared methods of the given class.
1794 c ............ class to get the methods of
1795 publicOnly ... show only public methods
1798 array of java.lang.reflect.Method
1800 *******************************************************************************/
1802 #if defined(ENABLE_JAVASE)
1803 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1805 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1806 methodinfo *m; /* the current method to be represented */
1812 /* JOWENN: array classes do not declare methods according to mauve
1813 test. It should be considered, if we should return to my old
1814 clone method overriding instead of declaring it as a member
1817 if (class_is_array(c))
1818 return builtin_anewarray(0, class_java_lang_reflect_Method);
1820 /* Determine number of methods. */
1824 for (i = 0; i < c->methodscount; i++) {
1825 m = &(c->methods[i]);
1827 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1828 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1829 !(m->flags & ACC_MIRANDA))
1833 /* Create array of methods. */
1835 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1840 /* Get the methods and store them in the array. */
1842 for (i = 0, index = 0; i < c->methodscount; i++) {
1843 m = &(c->methods[i]);
1845 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1846 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1847 !(m->flags & ACC_MIRANDA)) {
1848 // Create java.lang.reflect.Method object.
1850 h = java_lang_reflect_Method_create(m);
1852 /* Store object into array. */
1854 array_objectarray_element_set(oa, index, h);
1864 /* class_get_declaringclass ****************************************************
1866 If the class or interface given is a member of another class,
1867 return the declaring class. For array and primitive classes return
1870 *******************************************************************************/
1872 classinfo *class_get_declaringclass(classinfo *c)
1874 classref_or_classinfo cr;
1877 /* Get declaring class. */
1879 cr = c->declaringclass;
1884 /* Resolve the class if necessary. */
1886 if (IS_CLASSREF(cr)) {
1887 /* dc = resolve_classref_eager(cr.ref); */
1888 dc = resolve_classref_or_classinfo_eager(cr, true);
1893 /* Store the resolved class in the class structure. */
1904 /* class_get_enclosingclass ****************************************************
1906 Return the enclosing class for the given class.
1908 *******************************************************************************/
1910 classinfo *class_get_enclosingclass(classinfo *c)
1912 classref_or_classinfo cr;
1915 /* Get enclosing class. */
1917 cr = c->enclosingclass;
1922 /* Resolve the class if necessary. */
1924 if (IS_CLASSREF(cr)) {
1925 /* ec = resolve_classref_eager(cr.ref); */
1926 ec = resolve_classref_or_classinfo_eager(cr, true);
1931 /* Store the resolved class in the class structure. */
1943 * Return the enclosing constructor as java.lang.reflect.Constructor
1944 * object for the given class.
1946 * @param c class to return the enclosing constructor for
1948 * @return java.lang.reflect.Constructor object of the enclosing
1951 #if defined(ENABLE_JAVASE)
1952 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1957 m = class_get_enclosingmethod_raw(c);
1962 /* Check for <init>. */
1964 if (m->name != utf_init)
1967 // Create a java.lang.reflect.Constructor object.
1969 rc = java_lang_reflect_Constructor_create(m);
1976 /* class_get_enclosingmethod ***************************************************
1978 Return the enclosing method for the given class.
1981 c ... class to return the enclosing method for
1984 methodinfo of the enclosing method
1986 *******************************************************************************/
1988 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1990 constant_nameandtype *cn;
1994 /* get enclosing class and method */
1996 ec = class_get_enclosingclass(c);
1997 cn = c->enclosingmethod;
1999 /* check for enclosing class and method */
2007 /* find method in enclosing class */
2009 m = class_findmethod(ec, cn->name, cn->descriptor);
2012 exceptions_throw_internalerror("Enclosing method doesn't exist");
2021 * Return the enclosing method as java.lang.reflect.Method object for
2024 * @param c class to return the enclosing method for
2026 * @return java.lang.reflect.Method object of the enclosing method
2028 #if defined(ENABLE_JAVASE)
2029 java_handle_t* class_get_enclosingmethod(classinfo *c)
2034 m = class_get_enclosingmethod_raw(c);
2039 /* check for <init> */
2041 if (m->name == utf_init)
2044 // Create a java.lang.reflect.Method object.
2046 rm = java_lang_reflect_Method_create(m);
2053 /* class_get_interfaces ********************************************************
2055 Return an array of interfaces of the given class.
2057 *******************************************************************************/
2059 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2062 java_handle_objectarray_t *oa;
2065 if (!(c->state & CLASS_LINKED))
2069 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2074 for (i = 0; i < c->interfacescount; i++) {
2075 ic = c->interfaces[i];
2077 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2084 /* class_get_annotations *******************************************************
2086 Get the unparsed declared annotations in a byte array
2090 c........the class of which the annotations should be returned
2093 The unparsed declared annotations in a byte array
2094 (or NULL if there aren't any).
2096 *******************************************************************************/
2098 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2100 #if defined(ENABLE_ANNOTATIONS)
2101 java_handle_t *annotations; /* unparsed annotations */
2103 LLNI_classinfo_field_get(c, annotations, annotations);
2105 return (java_handle_bytearray_t*)annotations;
2112 /* class_get_modifiers *********************************************************
2114 Get the modifier flags of the given class.
2117 c....the class of which the modifier flags should be returned
2118 ignoreInnerClassesAttrib
2122 *******************************************************************************/
2124 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2126 classref_or_classinfo inner;
2127 classref_or_classinfo outer;
2131 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2132 /* search for passed class as inner class */
2134 for (i = 0; i < c->innerclasscount; i++) {
2135 inner = c->innerclass[i].inner_class;
2136 outer = c->innerclass[i].outer_class;
2138 /* Check if inner is a classref or a real class and get
2139 the name of the structure */
2141 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2143 /* innerclass is this class */
2145 if (innername == c->name) {
2146 /* has the class actually an outer class? */
2149 /* return flags got from the outer class file */
2150 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2152 return c->flags & ACC_CLASS_REFLECT_MASK;
2157 /* passed class is no inner class or it was not requested */
2159 return c->flags & ACC_CLASS_REFLECT_MASK;
2163 /* class_get_signature *********************************************************
2165 Return the signature of the given class. For array and primitive
2166 classes return NULL.
2168 *******************************************************************************/
2170 #if defined(ENABLE_JAVASE)
2171 utf *class_get_signature(classinfo *c)
2173 /* For array and primitive classes return NULL. */
2175 if (class_is_array(c) || class_is_primitive(c))
2178 return c->signature;
2183 /* class_printflags ************************************************************
2185 Prints flags of a class.
2187 *******************************************************************************/
2189 #if !defined(NDEBUG)
2190 void class_printflags(classinfo *c)
2197 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2198 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2199 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2200 if (c->flags & ACC_STATIC) printf(" STATIC");
2201 if (c->flags & ACC_FINAL) printf(" FINAL");
2202 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2203 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2204 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2205 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2206 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2207 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2212 /* class_print *****************************************************************
2214 Prints classname plus flags.
2216 *******************************************************************************/
2218 #if !defined(NDEBUG)
2219 void class_print(classinfo *c)
2226 utf_display_printable_ascii(c->name);
2227 class_printflags(c);
2232 /* class_classref_print ********************************************************
2234 Prints classname plus referer class.
2236 *******************************************************************************/
2238 #if !defined(NDEBUG)
2239 void class_classref_print(constant_classref *cr)
2246 utf_display_printable_ascii(cr->name);
2249 class_print(cr->referer);
2257 /* class_println ***************************************************************
2259 Prints classname plus flags and new line.
2261 *******************************************************************************/
2263 #if !defined(NDEBUG)
2264 void class_println(classinfo *c)
2272 /* class_classref_println ******************************************************
2274 Prints classname plus referer class and new line.
2276 *******************************************************************************/
2278 #if !defined(NDEBUG)
2279 void class_classref_println(constant_classref *cr)
2281 class_classref_print(cr);
2287 /* class_classref_or_classinfo_print *******************************************
2289 Prints classname plus referer class.
2291 *******************************************************************************/
2293 #if !defined(NDEBUG)
2294 void class_classref_or_classinfo_print(classref_or_classinfo c)
2296 if (c.any == NULL) {
2297 printf("(classref_or_classinfo) NULL");
2301 class_classref_print(c.ref);
2308 /* class_classref_or_classinfo_println *****************************************
2310 Prints classname plus referer class and a newline.
2312 *******************************************************************************/
2314 #if !defined(NDEBUG)
2315 void class_classref_or_classinfo_println(classref_or_classinfo c)
2317 class_classref_or_classinfo_print(c);
2323 /* class_showconstantpool ******************************************************
2325 Dump the constant pool of the given class to stdout.
2327 *******************************************************************************/
2329 #if !defined(NDEBUG)
2330 void class_showconstantpool (classinfo *c)
2335 printf ("---- dump of constant pool ----\n");
2337 for (i=0; i<c->cpcount; i++) {
2338 printf ("#%d: ", (int) i);
2340 e = c -> cpinfos [i];
2343 switch (c -> cptags [i]) {
2344 case CONSTANT_Class:
2345 printf ("Classreference -> ");
2346 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2348 case CONSTANT_Fieldref:
2349 printf ("Fieldref -> ");
2350 field_fieldref_print((constant_FMIref *) e);
2352 case CONSTANT_Methodref:
2353 printf ("Methodref -> ");
2354 method_methodref_print((constant_FMIref *) e);
2356 case CONSTANT_InterfaceMethodref:
2357 printf ("InterfaceMethod -> ");
2358 method_methodref_print((constant_FMIref *) e);
2360 case CONSTANT_String:
2361 printf ("String -> ");
2362 utf_display_printable_ascii (e);
2364 case CONSTANT_Integer:
2365 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2367 case CONSTANT_Float:
2368 printf ("Float -> %f", ((constant_float*)e) -> value);
2370 case CONSTANT_Double:
2371 printf ("Double -> %f", ((constant_double*)e) -> value);
2374 printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
2376 case CONSTANT_NameAndType:
2378 constant_nameandtype *cnt = e;
2379 printf ("NameAndType: ");
2380 utf_display_printable_ascii (cnt->name);
2382 utf_display_printable_ascii (cnt->descriptor);
2386 printf ("Utf8 -> ");
2387 utf_display_printable_ascii (e);
2390 log_text("Invalid type of ConstantPool-Entry");
2398 #endif /* !defined(NDEBUG) */
2401 /* class_showmethods ***********************************************************
2403 Dump info about the fields and methods of the given class to stdout.
2405 *******************************************************************************/
2407 #if !defined(NDEBUG)
2408 void class_showmethods (classinfo *c)
2412 printf("--------- Fields and Methods ----------------\n");
2414 class_printflags(c);
2418 utf_display_printable_ascii(c->name);
2423 utf_display_printable_ascii(c->super->name);
2427 printf("Index: %d\n", c->index);
2429 printf("Interfaces:\n");
2430 for (i = 0; i < c->interfacescount; i++) {
2432 utf_display_printable_ascii(c->interfaces[i]->name);
2433 printf (" (%d)\n", c->interfaces[i]->index);
2436 printf("Fields:\n");
2437 for (i = 0; i < c->fieldscount; i++)
2438 field_println(&(c->fields[i]));
2440 printf("Methods:\n");
2441 for (i = 0; i < c->methodscount; i++) {
2442 methodinfo *m = &(c->methods[i]);
2444 if (!(m->flags & ACC_STATIC))
2445 printf("vftblindex: %d ", m->vftblindex);
2450 printf ("Virtual function table:\n");
2451 for (i = 0; i < c->vftbl->vftbllength; i++)
2452 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2454 #endif /* !defined(NDEBUG) */
2458 * These are local overrides for various environment variables in Emacs.
2459 * Please do not remove this and leave it at the end of the file, where
2460 * Emacs will automagically detect them.
2461 * ---------------------------------------------------------------------
2464 * indent-tabs-mode: t
2468 * vim:noexpandtab:sw=4:ts=4: