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-common.h"
43 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
48 #include "vm/classcache.h"
49 #include "vm/exceptions.hpp"
50 #include "vm/global.h"
51 #include "vm/globals.hpp"
52 #include "vm/javaobjects.hpp"
53 #include "vm/jit/jitcache.h"
54 #include "vm/linker.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
59 #if defined(ENABLE_STATISTICS)
60 # include "vm/statistics.h"
66 #include "vm/jit/asmpart.h"
69 /* class_set_packagename *******************************************************
71 Derive the package name from the class name and store it in the
74 An internal package name consists of the package name plus the
75 trailing '/', e.g. "java/lang/".
77 For classes in the unnamed package, the package name is set to
80 *******************************************************************************/
82 void class_set_packagename(classinfo *c)
87 p = UTF_END(c->name) - 1;
88 start = c->name->text;
90 if (c->name->text[0] == '[') {
91 /* Set packagename of arrays to the element's package. */
93 for (; *start == '['; start++);
95 /* Skip the 'L' in arrays of references. */
101 /* Search for last '/'. */
103 for (; (p > start) && (*p != '/'); --p);
105 /* If we found a '/' we set the package name plus the trailing
106 '/'. Otherwise we set the packagename to NULL. */
109 c->packagename = utf_new(start, p - start + 1);
111 c->packagename = NULL;
115 /* class_create_classinfo ******************************************************
117 Create a new classinfo struct. The class name is set to the given utf *,
118 most other fields are initialized to zero.
120 Note: classname may be NULL. In this case a not-yet-named classinfo is
121 created. The name must be filled in later and class_set_packagename
122 must be called after that.
124 *******************************************************************************/
126 classinfo *class_create_classinfo(utf *classname)
130 #if defined(ENABLE_STATISTICS)
132 size_classinfo += sizeof(classinfo);
135 /* we use a safe name for temporarily unnamed classes */
137 if (classname == NULL)
138 classname = utf_not_named_yet;
142 log_message_utf("Creating class: ", classname);
145 #if !defined(ENABLE_GC_BOEHM)
146 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
147 /*c = NEW(classinfo);
148 MZERO(c, classinfo, 1);*/
150 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
151 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
156 /* Set the header.vftbl of all loaded classes to the one of
157 java.lang.Class, so Java code can use a class as object. */
159 if (class_java_lang_Class != NULL)
160 if (class_java_lang_Class->vftbl != NULL)
161 c->object.header.vftbl = class_java_lang_Class->vftbl;
163 #if defined(ENABLE_JAVASE)
164 /* check if the class is a reference class and flag it */
166 if (classname == utf_java_lang_ref_SoftReference) {
167 c->flags |= ACC_CLASS_REFERENCE_SOFT;
169 else if (classname == utf_java_lang_ref_WeakReference) {
170 c->flags |= ACC_CLASS_REFERENCE_WEAK;
172 else if (classname == utf_java_lang_ref_PhantomReference) {
173 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
177 if (classname != utf_not_named_yet)
178 class_set_packagename(c);
179 #if defined (ENABLE_JITCACHE)
180 c->cache_file_fd = 0;
183 LOCK_INIT_OBJECT_LOCK(&c->object.header);
189 /* class_postset_header_vftbl **************************************************
191 Set the header.vftbl of all classes created before java.lang.Class
192 was linked. This is necessary that Java code can use a class as
195 *******************************************************************************/
197 void class_postset_header_vftbl(void)
201 classcache_name_entry *nmen;
202 classcache_class_entry *clsen;
204 assert(class_java_lang_Class);
206 for (slot = 0; slot < hashtable_classcache.size; slot++) {
207 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
209 for (; nmen; nmen = nmen->hashlink) {
210 /* iterate over all class entries */
212 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
215 /* now set the the vftbl */
217 if (c->object.header.vftbl == NULL)
218 c->object.header.vftbl = class_java_lang_Class->vftbl;
224 /* class_define ****************************************************************
226 Calls the loader and defines a class in the VM.
228 *******************************************************************************/
230 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
237 /* check if this class has already been defined */
239 c = classcache_lookup_defined_or_initiated(cl, name);
242 exceptions_throw_linkageerror("duplicate class definition: ", c);
247 /* create a new classinfo struct */
249 c = class_create_classinfo(name);
251 #if defined(ENABLE_STATISTICS)
254 if (opt_getloadingtime)
258 /* build a classbuffer with the given data */
260 cb = NEW(classbuffer);
267 /* preset the defining classloader */
271 /* load the class from this buffer */
273 r = load_class_from_classbuffer(cb);
277 FREE(cb, classbuffer);
279 #if defined(ENABLE_STATISTICS)
282 if (opt_getloadingtime)
287 /* If return value is NULL, we had a problem and the class is
288 not loaded. Now free the allocated memory, otherwise we
289 could run into a DOS. */
296 #if defined(ENABLE_JAVASE)
297 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
298 /* Store the protection domain. */
300 c->protectiondomain = pd;
304 /* Store the newly defined class in the class cache. This call
305 also checks whether a class of the same name has already been
306 defined by the same defining loader, and if so, replaces the
307 newly created class by the one defined earlier. */
309 /* Important: The classinfo given to classcache_store must be
310 fully prepared because another thread may return
311 this pointer after the lookup at to top of this
312 function directly after the class cache lock has
315 c = classcache_store(cl, c, true);
321 /* class_load_attribute_sourcefile *********************************************
323 SourceFile_attribute {
324 u2 attribute_name_index;
329 *******************************************************************************/
331 static bool class_load_attribute_sourcefile(classbuffer *cb)
342 /* check buffer size */
344 if (!suck_check_classbuffer_size(cb, 4 + 2))
347 /* check attribute length */
349 attribute_length = suck_u4(cb);
351 if (attribute_length != 2) {
352 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
356 /* there can be no more than one SourceFile attribute */
358 if (c->sourcefile != NULL) {
359 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
365 sourcefile_index = suck_u2(cb);
366 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
368 if (sourcefile == NULL)
371 /* store sourcefile */
373 c->sourcefile = sourcefile;
379 /* class_load_attribute_enclosingmethod ****************************************
381 EnclosingMethod_attribute {
382 u2 attribute_name_index;
388 *******************************************************************************/
390 #if defined(ENABLE_JAVASE)
391 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
397 classref_or_classinfo cr;
398 constant_nameandtype *cn;
404 /* check buffer size */
406 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
409 /* check attribute length */
411 attribute_length = suck_u4(cb);
413 if (attribute_length != 4) {
414 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
418 /* there can be no more than one EnclosingMethod attribute */
420 if (c->enclosingmethod != NULL) {
421 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
425 /* get class index */
427 class_index = suck_u2(cb);
428 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
430 /* get method index */
432 method_index = suck_u2(cb);
433 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
435 /* store info in classinfo */
437 c->enclosingclass.any = cr.any;
438 c->enclosingmethod = cn;
442 #endif /* defined(ENABLE_JAVASE) */
445 /* class_load_attributes *******************************************************
447 Read attributes from ClassFile.
450 u2 attribute_name_index;
452 u1 info[attribute_length];
455 InnerClasses_attribute {
456 u2 attribute_name_index;
460 *******************************************************************************/
462 bool class_load_attributes(classbuffer *cb)
465 uint16_t attributes_count;
466 uint16_t attribute_name_index;
468 innerclassinfo *info;
469 classref_or_classinfo inner;
470 classref_or_classinfo outer;
477 /* get attributes count */
479 if (!suck_check_classbuffer_size(cb, 2))
482 attributes_count = suck_u2(cb);
484 for (i = 0; i < attributes_count; i++) {
485 /* get attribute name */
487 if (!suck_check_classbuffer_size(cb, 2))
490 attribute_name_index = suck_u2(cb);
492 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
494 if (attribute_name == NULL)
497 if (attribute_name == utf_InnerClasses) {
500 if (c->innerclass != NULL) {
501 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
505 if (!suck_check_classbuffer_size(cb, 4 + 2))
508 /* skip attribute length */
511 /* number of records */
512 c->innerclasscount = suck_u2(cb);
514 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
517 /* allocate memory for innerclass structure */
518 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
520 for (j = 0; j < c->innerclasscount; j++) {
521 /* The innerclass structure contains a class with an encoded
522 name, its defining scope, its simple name and a bitmask of
525 info = c->innerclass + j;
527 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
528 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
529 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
532 /* If the current inner-class is the currently loaded
533 class check for some special flags. */
535 if (inner.ref->name == c->name) {
536 /* If an inner-class is not a member, its
537 outer-class is NULL. */
539 if (outer.ref != NULL) {
540 c->flags |= ACC_CLASS_MEMBER;
542 /* A member class doesn't have an
543 EnclosingMethod attribute, so set the
544 enclosing-class to be the same as the
547 c->declaringclass = outer;
548 c->enclosingclass = outer;
551 /* If an inner-class is anonymous, its name is
555 c->flags |= ACC_CLASS_ANONYMOUS;
558 info->inner_class = inner;
559 info->outer_class = outer;
564 else if (attribute_name == utf_SourceFile) {
567 if (!class_load_attribute_sourcefile(cb))
570 #if defined(ENABLE_JAVASE)
571 else if (attribute_name == utf_EnclosingMethod) {
572 /* EnclosingMethod */
574 if (!class_load_attribute_enclosingmethod(cb))
577 else if (attribute_name == utf_Signature) {
580 if (!loader_load_attribute_signature(cb, &(c->signature)))
585 #if defined(ENABLE_ANNOTATIONS)
586 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
587 /* RuntimeVisibleAnnotations */
588 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
591 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
592 /* RuntimeInvisibleAnnotations */
593 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
599 /* unknown attribute */
601 if (!loader_skip_attribute_body(cb))
610 /* class_freepool **************************************************************
612 Frees all resources used by this classes Constant Pool.
614 *******************************************************************************/
616 static void class_freecpool(classinfo *c)
622 if (c->cptags && c->cpinfos) {
623 for (idx = 0; idx < c->cpcount; idx++) {
624 tag = c->cptags[idx];
625 info = c->cpinfos[idx];
629 case CONSTANT_Fieldref:
630 case CONSTANT_Methodref:
631 case CONSTANT_InterfaceMethodref:
632 FREE(info, constant_FMIref);
634 case CONSTANT_Integer:
635 FREE(info, constant_integer);
638 FREE(info, constant_float);
641 FREE(info, constant_long);
643 case CONSTANT_Double:
644 FREE(info, constant_double);
646 case CONSTANT_NameAndType:
647 FREE(info, constant_nameandtype);
655 MFREE(c->cptags, u1, c->cpcount);
658 MFREE(c->cpinfos, void*, c->cpcount);
662 /* class_getconstant ***********************************************************
664 Retrieves the value at position 'pos' of the constantpool of a
665 class. If the type of the value is other than 'ctype', an error is
668 *******************************************************************************/
670 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
672 /* check index and type of constantpool entry */
673 /* (pos == 0 is caught by type comparison) */
675 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
676 exceptions_throw_classformaterror(c, "Illegal constant pool index");
680 return c->cpinfos[pos];
684 /* innerclass_getconstant ******************************************************
686 Like class_getconstant, but if cptags is ZERO, null is returned.
688 *******************************************************************************/
690 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
692 /* invalid position in constantpool */
694 if (pos >= c->cpcount) {
695 exceptions_throw_classformaterror(c, "Illegal constant pool index");
699 /* constantpool entry of type 0 */
701 if (c->cptags[pos] == 0)
704 /* check type of constantpool entry */
706 if (c->cptags[pos] != ctype) {
707 exceptions_throw_classformaterror(c, "Illegal constant pool index");
711 return c->cpinfos[pos];
715 /* class_free ******************************************************************
717 Frees all resources used by the class.
719 *******************************************************************************/
721 void class_free(classinfo *c)
726 #if defined(ENABLE_JITCACHE)
727 /* TODO: Find a way around the linker problem */
728 /* jitcache_freeclass(c);*/
733 if (c->interfaces != NULL)
734 MFREE(c->interfaces, classinfo*, c->interfacescount);
737 for (i = 0; i < c->fieldscount; i++)
738 field_free(&(c->fields[i]));
739 MFREE(c->fields, fieldinfo, c->fieldscount);
743 for (i = 0; i < c->methodscount; i++)
744 method_free(&(c->methods[i]));
745 MFREE(c->methods, methodinfo, c->methodscount);
748 if ((v = c->vftbl) != NULL) {
750 mem_free(v->arraydesc,sizeof(arraydescriptor));
752 for (i = 0; i < v->interfacetablelength; i++) {
753 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
755 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
757 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
758 sizeof(methodptr*) * (v->interfacetablelength -
759 (v->interfacetablelength > 0));
760 v = (vftbl_t*) (((methodptr*) v) -
761 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
766 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
768 /* if (c->classvftbl)
769 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
775 /* get_array_class *************************************************************
777 Returns the array class with the given name for the given
778 classloader, or NULL if an exception occurred.
780 Note: This function does eager loading.
782 *******************************************************************************/
784 static classinfo *get_array_class(utf *name,classloader_t *initloader,
785 classloader_t *defloader,bool link)
789 /* lookup this class in the classcache */
790 c = classcache_lookup(initloader,name);
792 c = classcache_lookup_defined(defloader,name);
795 /* we have to create it */
796 c = class_create_classinfo(name);
797 c = load_newly_created_array(c,initloader);
803 assert(c->state & CLASS_LOADED);
804 assert(c->classloader == defloader);
806 if (link && !(c->state & CLASS_LINKED))
810 assert(!link || (c->state & CLASS_LINKED));
816 /* class_array_of **************************************************************
818 Returns an array class with the given component class. The array
819 class is dynamically created if neccessary.
821 *******************************************************************************/
823 classinfo *class_array_of(classinfo *component, bool link)
832 cl = component->classloader;
836 /* Assemble the array class name */
837 namelen = component->name->blength;
839 if (component->name->text[0] == '[') {
840 /* the component is itself an array */
841 namebuf = DMNEW(char, namelen + 1);
843 MCOPY(namebuf + 1, component->name->text, char, namelen);
847 /* the component is a non-array class */
848 namebuf = DMNEW(char, namelen + 3);
851 MCOPY(namebuf + 2, component->name->text, char, namelen);
852 namebuf[2 + namelen] = ';';
856 u = utf_new(namebuf, namelen);
858 c = get_array_class(u, cl, cl, link);
866 /* class_multiarray_of *********************************************************
868 Returns an array class with the given dimension and element class.
869 The array class is dynamically created if neccessary.
871 *******************************************************************************/
873 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
883 log_text("Invalid array dimension requested");
887 /* Assemble the array class name */
888 namelen = element->name->blength;
890 if (element->name->text[0] == '[') {
891 /* the element is itself an array */
892 namebuf = DMNEW(char, namelen + dim);
893 memcpy(namebuf + dim, element->name->text, namelen);
897 /* the element is a non-array class */
898 namebuf = DMNEW(char, namelen + 2 + dim);
900 memcpy(namebuf + dim + 1, element->name->text, namelen);
901 namelen += (2 + dim);
902 namebuf[namelen - 1] = ';';
904 memset(namebuf, '[', dim);
906 c = get_array_class(utf_new(namebuf, namelen),
907 element->classloader,
908 element->classloader,
917 /* class_lookup_classref *******************************************************
919 Looks up the constant_classref for a given classname in the classref
923 cls..............the class containing the reference
924 name.............the name of the class refered to
927 a pointer to a constant_classref, or
928 NULL if the reference was not found
930 *******************************************************************************/
932 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
934 constant_classref *ref;
935 extra_classref *xref;
940 assert(!cls->classrefcount || cls->classrefs);
942 /* first search the main classref table */
943 count = cls->classrefcount;
944 ref = cls->classrefs;
945 for (; count; --count, ++ref)
946 if (ref->name == name)
949 /* next try the list of extra classrefs */
950 for (xref = cls->extclassrefs; xref; xref = xref->next) {
951 if (xref->classref.name == name)
952 return &(xref->classref);
960 /* class_get_classref **********************************************************
962 Returns the constant_classref for a given classname.
965 cls..............the class containing the reference
966 name.............the name of the class refered to
969 a pointer to a constant_classref (never NULL)
972 The given name is not checked for validity!
974 *******************************************************************************/
976 constant_classref *class_get_classref(classinfo *cls, utf *name)
978 constant_classref *ref;
979 extra_classref *xref;
984 ref = class_lookup_classref(cls,name);
988 xref = NEW(extra_classref);
989 CLASSREF_INIT(xref->classref,cls,name);
991 xref->next = cls->extclassrefs;
992 cls->extclassrefs = xref;
994 return &(xref->classref);
998 /* class_get_self_classref *****************************************************
1000 Returns the constant_classref to the class itself.
1003 cls..............the class containing the reference
1006 a pointer to a constant_classref (never NULL)
1008 *******************************************************************************/
1010 constant_classref *class_get_self_classref(classinfo *cls)
1012 /* XXX this should be done in a faster way. Maybe always make */
1013 /* the classref of index 0 a self reference. */
1014 return class_get_classref(cls,cls->name);
1017 /* class_get_classref_multiarray_of ********************************************
1019 Returns an array type reference with the given dimension and element class
1023 dim..............the requested dimension
1024 dim must be in [1;255]. This is NOT checked!
1025 ref..............the component class reference
1028 a pointer to the class reference for the array type
1031 The referer of `ref` is used as the referer for the new classref.
1033 *******************************************************************************/
1035 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1039 constant_classref *cr;
1043 assert(dim >= 1 && dim <= 255);
1047 /* Assemble the array class name */
1048 namelen = ref->name->blength;
1050 if (ref->name->text[0] == '[') {
1051 /* the element is itself an array */
1052 namebuf = DMNEW(char, namelen + dim);
1053 memcpy(namebuf + dim, ref->name->text, namelen);
1057 /* the element is a non-array class */
1058 namebuf = DMNEW(char, namelen + 2 + dim);
1060 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1061 namelen += (2 + dim);
1062 namebuf[namelen - 1] = ';';
1064 memset(namebuf, '[', dim);
1066 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1074 /* class_get_classref_component_of *********************************************
1076 Returns the component classref of a given array type reference
1079 ref..............the array type reference
1082 a reference to the component class, or
1083 NULL if `ref` is not an object array type reference
1086 The referer of `ref` is used as the referer for the new classref.
1088 *******************************************************************************/
1090 constant_classref *class_get_classref_component_of(constant_classref *ref)
1097 name = ref->name->text;
1101 namelen = ref->name->blength - 1;
1106 else if (*name != '[') {
1110 return class_get_classref(ref->referer, utf_new(name, namelen));
1114 /* class_findmethod ************************************************************
1116 Searches a 'classinfo' structure for a method having the given name
1117 and descriptor. If descriptor is NULL, it is ignored.
1119 *******************************************************************************/
1121 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1126 for (i = 0; i < c->methodscount; i++) {
1127 m = &(c->methods[i]);
1129 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1137 /* class_resolvemethod *********************************************************
1139 Searches a class and it's super classes for a method.
1141 Superinterfaces are *not* searched.
1143 *******************************************************************************/
1145 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1150 m = class_findmethod(c, name, desc);
1155 /* JVM Specification bug:
1157 It is important NOT to resolve special <init> and <clinit>
1158 methods to super classes or interfaces; yet, this is not
1159 explicited in the specification. Section 5.4.3.3 should be
1160 updated appropriately. */
1162 if (name == utf_init || name == utf_clinit)
1172 /* class_resolveinterfacemethod_intern *****************************************
1174 Internally used helper function. Do not use this directly.
1176 *******************************************************************************/
1178 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1179 utf *name, utf *desc)
1184 /* try to find the method in the class */
1186 m = class_findmethod(c, name, desc);
1191 /* No method found? Try the super interfaces. */
1193 for (i = 0; i < c->interfacescount; i++) {
1194 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1200 /* no method found */
1206 /* class_resolveclassmethod ****************************************************
1208 Resolves a reference from REFERER to a method with NAME and DESC in
1211 If the method cannot be resolved the return value is NULL. If
1212 EXCEPT is true *exceptionptr is set, too.
1214 *******************************************************************************/
1216 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1217 classinfo *referer, bool throwexception)
1223 /* if (c->flags & ACC_INTERFACE) { */
1224 /* if (throwexception) */
1225 /* *exceptionptr = */
1226 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1230 /* try class c and its superclasses */
1234 m = class_resolvemethod(cls, name, desc);
1239 /* Try the super interfaces. */
1241 for (i = 0; i < c->interfacescount; i++) {
1242 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1249 exceptions_throw_nosuchmethoderror(c, name, desc);
1254 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1256 exceptions_throw_abstractmethoderror();
1261 /* XXX check access rights */
1267 /* class_resolveinterfacemethod ************************************************
1269 Resolves a reference from REFERER to a method with NAME and DESC in
1272 If the method cannot be resolved the return value is NULL. If
1273 EXCEPT is true *exceptionptr is set, too.
1275 *******************************************************************************/
1277 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1278 classinfo *referer, bool throwexception)
1282 if (!(c->flags & ACC_INTERFACE)) {
1284 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1289 mi = class_resolveinterfacemethod_intern(c, name, desc);
1294 /* try class java.lang.Object */
1296 mi = class_findmethod(class_java_lang_Object, name, desc);
1302 exceptions_throw_nosuchmethoderror(c, name, desc);
1308 /* class_findfield *************************************************************
1310 Searches for field with specified name and type in a classinfo
1311 structure. If no such field is found NULL is returned.
1313 *******************************************************************************/
1315 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1319 for (i = 0; i < c->fieldscount; i++)
1320 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1321 return &(c->fields[i]);
1323 if (c->super != NULL)
1324 return class_findfield(c->super, name, desc);
1330 /* class_findfield_approx ******************************************************
1332 Searches in 'classinfo'-structure for a field with the specified
1335 *******************************************************************************/
1337 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1339 for (int32_t i = 0; i < c->fieldscount; i++) {
1340 fieldinfo* f = &(c->fields[i]);
1342 if (f->name == name)
1347 exceptions_throw_nosuchfielderror(c, name);
1352 /****************** Function: class_resolvefield_int ***************************
1354 This is an internally used helper function. Do not use this directly.
1356 Tries to resolve a field having the given name and type.
1357 If the field cannot be resolved, NULL is returned.
1359 *******************************************************************************/
1361 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1366 /* search for field in class c */
1368 for (i = 0; i < c->fieldscount; i++) {
1369 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1370 return &(c->fields[i]);
1374 /* Try super interfaces recursively. */
1376 for (i = 0; i < c->interfacescount; i++) {
1377 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1383 /* Try super class. */
1385 if (c->super != NULL)
1386 return class_resolvefield_int(c->super, name, desc);
1394 /********************* Function: class_resolvefield ***************************
1396 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1398 If the field cannot be resolved, an exception is thrown and the
1399 return value is NULL.
1401 *******************************************************************************/
1403 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1407 fi = class_resolvefield_int(c, name, desc);
1410 exceptions_throw_nosuchfielderror(c, name);
1414 /* XXX check access rights */
1420 /* class_issubclass ************************************************************
1422 Checks if sub is a descendant of super.
1424 *******************************************************************************/
1426 bool class_issubclass(classinfo *sub, classinfo *super)
1433 /* We reached java/lang/Object and did not find the requested
1439 /* We found the requested super class. */
1449 /* class_isanysubclass *********************************************************
1451 Checks a subclass relation between two classes. Implemented
1452 interfaces are interpreted as super classes.
1454 Return value: 1 ... sub is subclass of super
1457 *******************************************************************************/
1459 bool class_isanysubclass(classinfo *sub, classinfo *super)
1464 /* This is the trivial case. */
1469 /* Primitive classes are only subclasses of themselves. */
1471 if (class_is_primitive(sub) || class_is_primitive(super))
1474 /* Check for interfaces. */
1476 if (super->flags & ACC_INTERFACE) {
1477 result = (sub->vftbl->interfacetablelength > super->index) &&
1478 (sub->vftbl->interfacetable[-super->index] != NULL);
1481 /* java.lang.Object is the only super class of any
1484 if (sub->flags & ACC_INTERFACE)
1485 return (super == class_java_lang_Object);
1487 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1489 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1490 result = diffval <= (uint32_t) super->vftbl->diffval;
1492 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1499 /* class_is_assignable_from ****************************************************
1501 Return whether an instance of the "from" class parameter would be
1502 an instance of this class "to" as well.
1509 true .... is assignable
1510 false ... is not assignable
1512 *******************************************************************************/
1514 bool class_is_assignable_from(classinfo *to, classinfo *from)
1516 if (!(to->state & CLASS_LINKED))
1517 if (!link_class(to))
1520 if (!(from->state & CLASS_LINKED))
1521 if (!link_class(from))
1524 return class_isanysubclass(from, to);
1528 /* class_is_instance ***********************************************************
1530 Return if the given Java object is an instance of the given class.
1537 true .... is instance
1538 false ... is not instance
1540 *******************************************************************************/
1542 bool class_is_instance(classinfo *c, java_handle_t *h)
1544 if (!(c->state & CLASS_LINKED))
1548 return builtin_instanceof(h, c);
1552 /* class_get_componenttype *****************************************************
1554 Return the component class of the given class. If the given class
1555 is not an array, return NULL.
1557 *******************************************************************************/
1559 classinfo *class_get_componenttype(classinfo *c)
1561 classinfo *component;
1562 arraydescriptor *ad;
1564 /* XXX maybe we could find a way to do this without linking. */
1565 /* This way should be safe and easy, however. */
1567 if (!(c->state & CLASS_LINKED))
1571 ad = c->vftbl->arraydesc;
1576 if (ad->arraytype == ARRAYTYPE_OBJECT)
1577 component = ad->componentvftbl->clazz;
1579 component = Primitive_get_class_by_type(ad->arraytype);
1585 /* class_get_declaredclasses ***************************************************
1587 Return an array of declared classes of the given class.
1589 *******************************************************************************/
1591 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1593 classref_or_classinfo inner;
1594 classref_or_classinfo outer;
1596 int declaredclasscount; /* number of declared classes */
1597 int pos; /* current declared class */
1598 java_handle_objectarray_t *oa; /* array of declared classes */
1602 declaredclasscount = 0;
1604 if (!class_is_primitive(c) && !class_is_array(c)) {
1605 /* Determine number of declared classes. */
1607 for (i = 0; i < c->innerclasscount; i++) {
1608 /* Get outer-class. If the inner-class is not a member
1609 class, the outer-class is NULL. */
1611 outer = c->innerclass[i].outer_class;
1613 if (outer.any == NULL)
1616 /* Check if outer-class is a classref or a real class and
1617 get the class name from the structure. */
1619 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1621 /* Outer class is this class. */
1623 if ((outername == c->name) &&
1624 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1625 declaredclasscount++;
1629 /* Allocate Class[] and check for OOM. */
1631 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1636 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1637 inner = c->innerclass[i].inner_class;
1638 outer = c->innerclass[i].outer_class;
1640 /* Get outer-class. If the inner-class is not a member class,
1641 the outer-class is NULL. */
1643 if (outer.any == NULL)
1646 /* Check if outer_class is a classref or a real class and get
1647 the class name from the structure. */
1649 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1651 /* Outer class is this class. */
1653 if ((outername == c->name) &&
1654 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1656 ic = resolve_classref_or_classinfo_eager(inner, false);
1661 if (!(ic->state & CLASS_LINKED))
1662 if (!link_class(ic))
1665 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1674 * Return an array of declared constructors of the given class.
1676 * @param c class to get the constructors of
1677 * @param publicOnly show only public fields
1679 * @return array of java.lang.reflect.Constructor
1681 #if defined(ENABLE_JAVASE)
1682 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1685 java_handle_objectarray_t* oa;
1691 /* Determine number of constructors. */
1695 for (i = 0; i < c->methodscount; i++) {
1696 m = &(c->methods[i]);
1698 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1699 (m->name == utf_init))
1703 /* Create array of constructors. */
1705 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1710 /* Get the constructors and store them in the array. */
1712 for (i = 0, index = 0; i < c->methodscount; i++) {
1713 m = &(c->methods[i]);
1715 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1716 (m->name == utf_init)) {
1717 // Create a java.lang.reflect.Constructor object.
1719 rc = java_lang_reflect_Constructor_create(m);
1721 /* Store object into array. */
1723 array_objectarray_element_set(oa, index, rc);
1733 /* class_get_declaredfields ****************************************************
1735 Return an array of declared fields of the given class.
1738 c ............ class to get the fields of
1739 publicOnly ... show only public fields
1742 array of java.lang.reflect.Field
1744 *******************************************************************************/
1746 #if defined(ENABLE_JAVASE)
1747 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1749 java_handle_objectarray_t *oa;
1756 /* Determine number of fields. */
1760 for (i = 0; i < c->fieldscount; i++)
1761 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1764 /* Create array of fields. */
1766 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1771 /* Get the fields and store them in the array. */
1773 for (i = 0, index = 0; i < c->fieldscount; i++) {
1774 f = &(c->fields[i]);
1776 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1777 // Create a java.lang.reflect.Field object.
1779 h = java_lang_reflect_Field_create(f);
1781 /* Store object into array. */
1783 array_objectarray_element_set(oa, index, h);
1793 /* class_get_declaredmethods ***************************************************
1795 Return an array of declared methods of the given class.
1798 c ............ class to get the methods of
1799 publicOnly ... show only public methods
1802 array of java.lang.reflect.Method
1804 *******************************************************************************/
1806 #if defined(ENABLE_JAVASE)
1807 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1809 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1810 methodinfo *m; /* the current method to be represented */
1816 /* JOWENN: array classes do not declare methods according to mauve
1817 test. It should be considered, if we should return to my old
1818 clone method overriding instead of declaring it as a member
1821 if (class_is_array(c))
1822 return builtin_anewarray(0, class_java_lang_reflect_Method);
1824 /* Determine number of methods. */
1828 for (i = 0; i < c->methodscount; i++) {
1829 m = &(c->methods[i]);
1831 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1832 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1833 !(m->flags & ACC_MIRANDA))
1837 /* Create array of methods. */
1839 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1844 /* Get the methods and store them in the array. */
1846 for (i = 0, index = 0; i < c->methodscount; i++) {
1847 m = &(c->methods[i]);
1849 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1850 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1851 !(m->flags & ACC_MIRANDA)) {
1852 // Create java.lang.reflect.Method object.
1854 h = java_lang_reflect_Method_create(m);
1856 /* Store object into array. */
1858 array_objectarray_element_set(oa, index, h);
1868 /* class_get_declaringclass ****************************************************
1870 If the class or interface given is a member of another class,
1871 return the declaring class. For array and primitive classes return
1874 *******************************************************************************/
1876 classinfo *class_get_declaringclass(classinfo *c)
1878 classref_or_classinfo cr;
1881 /* Get declaring class. */
1883 cr = c->declaringclass;
1888 /* Resolve the class if necessary. */
1890 if (IS_CLASSREF(cr)) {
1891 /* dc = resolve_classref_eager(cr.ref); */
1892 dc = resolve_classref_or_classinfo_eager(cr, true);
1897 /* Store the resolved class in the class structure. */
1908 /* class_get_enclosingclass ****************************************************
1910 Return the enclosing class for the given class.
1912 *******************************************************************************/
1914 classinfo *class_get_enclosingclass(classinfo *c)
1916 classref_or_classinfo cr;
1919 /* Get enclosing class. */
1921 cr = c->enclosingclass;
1926 /* Resolve the class if necessary. */
1928 if (IS_CLASSREF(cr)) {
1929 /* ec = resolve_classref_eager(cr.ref); */
1930 ec = resolve_classref_or_classinfo_eager(cr, true);
1935 /* Store the resolved class in the class structure. */
1947 * Return the enclosing constructor as java.lang.reflect.Constructor
1948 * object for the given class.
1950 * @param c class to return the enclosing constructor for
1952 * @return java.lang.reflect.Constructor object of the enclosing
1955 #if defined(ENABLE_JAVASE)
1956 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1961 m = class_get_enclosingmethod_raw(c);
1966 /* Check for <init>. */
1968 if (m->name != utf_init)
1971 // Create a java.lang.reflect.Constructor object.
1973 rc = java_lang_reflect_Constructor_create(m);
1980 /* class_get_enclosingmethod ***************************************************
1982 Return the enclosing method for the given class.
1985 c ... class to return the enclosing method for
1988 methodinfo of the enclosing method
1990 *******************************************************************************/
1992 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1994 constant_nameandtype *cn;
1998 /* get enclosing class and method */
2000 ec = class_get_enclosingclass(c);
2001 cn = c->enclosingmethod;
2003 /* check for enclosing class and method */
2011 /* find method in enclosing class */
2013 m = class_findmethod(ec, cn->name, cn->descriptor);
2016 exceptions_throw_internalerror("Enclosing method doesn't exist");
2025 * Return the enclosing method as java.lang.reflect.Method object for
2028 * @param c class to return the enclosing method for
2030 * @return java.lang.reflect.Method object of the enclosing method
2032 #if defined(ENABLE_JAVASE)
2033 java_handle_t* class_get_enclosingmethod(classinfo *c)
2038 m = class_get_enclosingmethod_raw(c);
2043 /* check for <init> */
2045 if (m->name == utf_init)
2048 // Create a java.lang.reflect.Method object.
2050 rm = java_lang_reflect_Method_create(m);
2057 /* class_get_interfaces ********************************************************
2059 Return an array of interfaces of the given class.
2061 *******************************************************************************/
2063 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2066 java_handle_objectarray_t *oa;
2069 if (!(c->state & CLASS_LINKED))
2073 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2078 for (i = 0; i < c->interfacescount; i++) {
2079 ic = c->interfaces[i];
2081 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2088 /* class_get_annotations *******************************************************
2090 Get the unparsed declared annotations in a byte array
2094 c........the class of which the annotations should be returned
2097 The unparsed declared annotations in a byte array
2098 (or NULL if there aren't any).
2100 *******************************************************************************/
2102 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2104 #if defined(ENABLE_ANNOTATIONS)
2105 java_handle_t *annotations; /* unparsed annotations */
2107 LLNI_classinfo_field_get(c, annotations, annotations);
2109 return (java_handle_bytearray_t*)annotations;
2116 /* class_get_modifiers *********************************************************
2118 Get the modifier flags of the given class.
2121 c....the class of which the modifier flags should be returned
2122 ignoreInnerClassesAttrib
2126 *******************************************************************************/
2128 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2130 classref_or_classinfo inner;
2131 classref_or_classinfo outer;
2135 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2136 /* search for passed class as inner class */
2138 for (i = 0; i < c->innerclasscount; i++) {
2139 inner = c->innerclass[i].inner_class;
2140 outer = c->innerclass[i].outer_class;
2142 /* Check if inner is a classref or a real class and get
2143 the name of the structure */
2145 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2147 /* innerclass is this class */
2149 if (innername == c->name) {
2150 /* has the class actually an outer class? */
2153 /* return flags got from the outer class file */
2154 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2156 return c->flags & ACC_CLASS_REFLECT_MASK;
2161 /* passed class is no inner class or it was not requested */
2163 return c->flags & ACC_CLASS_REFLECT_MASK;
2167 /* class_get_signature *********************************************************
2169 Return the signature of the given class. For array and primitive
2170 classes return NULL.
2172 *******************************************************************************/
2174 #if defined(ENABLE_JAVASE)
2175 utf *class_get_signature(classinfo *c)
2177 /* For array and primitive classes return NULL. */
2179 if (class_is_array(c) || class_is_primitive(c))
2182 return c->signature;
2187 /* class_printflags ************************************************************
2189 Prints flags of a class.
2191 *******************************************************************************/
2193 #if !defined(NDEBUG)
2194 void class_printflags(classinfo *c)
2201 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2202 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2203 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2204 if (c->flags & ACC_STATIC) printf(" STATIC");
2205 if (c->flags & ACC_FINAL) printf(" FINAL");
2206 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2207 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2208 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2209 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2210 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2211 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2216 /* class_print *****************************************************************
2218 Prints classname plus flags.
2220 *******************************************************************************/
2222 #if !defined(NDEBUG)
2223 void class_print(classinfo *c)
2230 utf_display_printable_ascii(c->name);
2231 class_printflags(c);
2236 /* class_classref_print ********************************************************
2238 Prints classname plus referer class.
2240 *******************************************************************************/
2242 #if !defined(NDEBUG)
2243 void class_classref_print(constant_classref *cr)
2250 utf_display_printable_ascii(cr->name);
2253 class_print(cr->referer);
2261 /* class_println ***************************************************************
2263 Prints classname plus flags and new line.
2265 *******************************************************************************/
2267 #if !defined(NDEBUG)
2268 void class_println(classinfo *c)
2276 /* class_classref_println ******************************************************
2278 Prints classname plus referer class and new line.
2280 *******************************************************************************/
2282 #if !defined(NDEBUG)
2283 void class_classref_println(constant_classref *cr)
2285 class_classref_print(cr);
2291 /* class_classref_or_classinfo_print *******************************************
2293 Prints classname plus referer class.
2295 *******************************************************************************/
2297 #if !defined(NDEBUG)
2298 void class_classref_or_classinfo_print(classref_or_classinfo c)
2300 if (c.any == NULL) {
2301 printf("(classref_or_classinfo) NULL");
2305 class_classref_print(c.ref);
2312 /* class_classref_or_classinfo_println *****************************************
2314 Prints classname plus referer class and a newline.
2316 *******************************************************************************/
2318 #if !defined(NDEBUG)
2319 void class_classref_or_classinfo_println(classref_or_classinfo c)
2321 class_classref_or_classinfo_print(c);
2327 /* class_showconstantpool ******************************************************
2329 Dump the constant pool of the given class to stdout.
2331 *******************************************************************************/
2333 #if !defined(NDEBUG)
2334 void class_showconstantpool (classinfo *c)
2339 printf ("---- dump of constant pool ----\n");
2341 for (i=0; i<c->cpcount; i++) {
2342 printf ("#%d: ", (int) i);
2344 e = c -> cpinfos [i];
2347 switch (c -> cptags [i]) {
2348 case CONSTANT_Class:
2349 printf ("Classreference -> ");
2350 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2352 case CONSTANT_Fieldref:
2353 printf ("Fieldref -> ");
2354 field_fieldref_print((constant_FMIref *) e);
2356 case CONSTANT_Methodref:
2357 printf ("Methodref -> ");
2358 method_methodref_print((constant_FMIref *) e);
2360 case CONSTANT_InterfaceMethodref:
2361 printf ("InterfaceMethod -> ");
2362 method_methodref_print((constant_FMIref *) e);
2364 case CONSTANT_String:
2365 printf ("String -> ");
2366 utf_display_printable_ascii (e);
2368 case CONSTANT_Integer:
2369 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2371 case CONSTANT_Float:
2372 printf ("Float -> %f", ((constant_float*)e) -> value);
2374 case CONSTANT_Double:
2375 printf ("Double -> %f", ((constant_double*)e) -> value);
2379 u8 v = ((constant_long*)e) -> value;
2381 printf ("Long -> %ld", (long int) v);
2383 printf ("Long -> HI: %ld, LO: %ld\n",
2384 (long int) v.high, (long int) v.low);
2388 case CONSTANT_NameAndType:
2390 constant_nameandtype *cnt = e;
2391 printf ("NameAndType: ");
2392 utf_display_printable_ascii (cnt->name);
2394 utf_display_printable_ascii (cnt->descriptor);
2398 printf ("Utf8 -> ");
2399 utf_display_printable_ascii (e);
2402 log_text("Invalid type of ConstantPool-Entry");
2410 #endif /* !defined(NDEBUG) */
2413 /* class_showmethods ***********************************************************
2415 Dump info about the fields and methods of the given class to stdout.
2417 *******************************************************************************/
2419 #if !defined(NDEBUG)
2420 void class_showmethods (classinfo *c)
2424 printf("--------- Fields and Methods ----------------\n");
2426 class_printflags(c);
2430 utf_display_printable_ascii(c->name);
2435 utf_display_printable_ascii(c->super->name);
2439 printf("Index: %d\n", c->index);
2441 printf("Interfaces:\n");
2442 for (i = 0; i < c->interfacescount; i++) {
2444 utf_display_printable_ascii(c->interfaces[i]->name);
2445 printf (" (%d)\n", c->interfaces[i]->index);
2448 printf("Fields:\n");
2449 for (i = 0; i < c->fieldscount; i++)
2450 field_println(&(c->fields[i]));
2452 printf("Methods:\n");
2453 for (i = 0; i < c->methodscount; i++) {
2454 methodinfo *m = &(c->methods[i]);
2456 if (!(m->flags & ACC_STATIC))
2457 printf("vftblindex: %d ", m->vftblindex);
2462 printf ("Virtual function table:\n");
2463 for (i = 0; i < c->vftbl->vftbllength; i++)
2464 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2466 #endif /* !defined(NDEBUG) */
2470 * These are local overrides for various environment variables in Emacs.
2471 * Please do not remove this and leave it at the end of the file, where
2472 * Emacs will automagically detect them.
2473 * ---------------------------------------------------------------------
2476 * indent-tabs-mode: t
2480 * vim:noexpandtab:sw=4:ts=4: