1 /* src/vm/class.cpp - 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.hpp"
39 #include "native/llni.h"
41 #include "threads/lock.hpp"
42 #include "threads/mutex.hpp"
44 #include "toolbox/logging.hpp"
46 #include "vm/array.hpp"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/class.hpp"
49 #include "vm/classcache.hpp"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/linker.hpp"
55 #include "vm/loader.hpp"
56 #include "vm/options.h"
57 #include "vm/resolve.hpp"
59 #if defined(ENABLE_STATISTICS)
60 # include "vm/statistics.h"
63 #include "vm/suck.hpp"
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);
180 c->object.header.lockword.init();
186 /* class_postset_header_vftbl **************************************************
188 Set the header.vftbl of all classes created before java.lang.Class
189 was linked. This is necessary that Java code can use a class as
192 *******************************************************************************/
194 void class_postset_header_vftbl(void)
198 classcache_name_entry *nmen;
199 classcache_class_entry *clsen;
201 assert(class_java_lang_Class);
203 for (slot = 0; slot < hashtable_classcache.size; slot++) {
204 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
206 for (; nmen; nmen = nmen->hashlink) {
207 /* iterate over all class entries */
209 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
212 /* now set the the vftbl */
214 if (c->object.header.vftbl == NULL)
215 c->object.header.vftbl = class_java_lang_Class->vftbl;
221 /* class_define ****************************************************************
223 Calls the loader and defines a class in the VM.
225 *******************************************************************************/
227 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
234 /* check if this class has already been defined */
236 c = classcache_lookup_defined_or_initiated(cl, name);
239 exceptions_throw_linkageerror("duplicate class definition: ", c);
244 /* create a new classinfo struct */
246 c = class_create_classinfo(name);
248 #if defined(ENABLE_STATISTICS)
251 if (opt_getloadingtime)
255 /* build a classbuffer with the given data */
257 cb = NEW(classbuffer);
264 /* preset the defining classloader */
268 /* load the class from this buffer */
270 r = load_class_from_classbuffer(cb);
274 FREE(cb, classbuffer);
276 #if defined(ENABLE_STATISTICS)
279 if (opt_getloadingtime)
284 /* If return value is NULL, we had a problem and the class is
285 not loaded. Now free the allocated memory, otherwise we
286 could run into a DOS. */
293 #if defined(ENABLE_JAVASE)
294 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
295 /* Store the protection domain. */
297 c->protectiondomain = pd;
301 /* Store the newly defined class in the class cache. This call
302 also checks whether a class of the same name has already been
303 defined by the same defining loader, and if so, replaces the
304 newly created class by the one defined earlier. */
306 /* Important: The classinfo given to classcache_store must be
307 fully prepared because another thread may return
308 this pointer after the lookup at to top of this
309 function directly after the class cache lock has
312 c = classcache_store(cl, c, true);
318 /* class_load_attribute_sourcefile *********************************************
320 SourceFile_attribute {
321 u2 attribute_name_index;
326 *******************************************************************************/
328 static bool class_load_attribute_sourcefile(classbuffer *cb)
339 /* check buffer size */
341 if (!suck_check_classbuffer_size(cb, 4 + 2))
344 /* check attribute length */
346 attribute_length = suck_u4(cb);
348 if (attribute_length != 2) {
349 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
353 /* there can be no more than one SourceFile attribute */
355 if (c->sourcefile != NULL) {
356 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
362 sourcefile_index = suck_u2(cb);
363 sourcefile = (utf*) class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
365 if (sourcefile == NULL)
368 /* store sourcefile */
370 c->sourcefile = sourcefile;
376 /* class_load_attribute_enclosingmethod ****************************************
378 EnclosingMethod_attribute {
379 u2 attribute_name_index;
385 *******************************************************************************/
387 #if defined(ENABLE_JAVASE)
388 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
394 classref_or_classinfo cr;
395 constant_nameandtype *cn;
401 /* check buffer size */
403 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
406 /* check attribute length */
408 attribute_length = suck_u4(cb);
410 if (attribute_length != 4) {
411 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
415 /* there can be no more than one EnclosingMethod attribute */
417 if (c->enclosingmethod != NULL) {
418 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
422 /* get class index */
424 class_index = suck_u2(cb);
425 cr.ref = (constant_classref*) innerclass_getconstant(c, class_index, CONSTANT_Class);
427 /* get method index */
429 method_index = suck_u2(cb);
430 cn = (constant_nameandtype*) innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
432 /* store info in classinfo */
434 c->enclosingclass.any = cr.any;
435 c->enclosingmethod = cn;
439 #endif /* defined(ENABLE_JAVASE) */
442 /* class_load_attributes *******************************************************
444 Read attributes from ClassFile.
447 u2 attribute_name_index;
449 u1 info[attribute_length];
452 InnerClasses_attribute {
453 u2 attribute_name_index;
457 *******************************************************************************/
459 bool class_load_attributes(classbuffer *cb)
462 uint16_t attributes_count;
463 uint16_t attribute_name_index;
465 innerclassinfo *info;
466 classref_or_classinfo inner;
467 classref_or_classinfo outer;
474 /* get attributes count */
476 if (!suck_check_classbuffer_size(cb, 2))
479 attributes_count = suck_u2(cb);
481 for (i = 0; i < attributes_count; i++) {
482 /* get attribute name */
484 if (!suck_check_classbuffer_size(cb, 2))
487 attribute_name_index = suck_u2(cb);
489 (utf*) class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
491 if (attribute_name == NULL)
494 if (attribute_name == utf_InnerClasses) {
497 if (c->innerclass != NULL) {
498 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
502 if (!suck_check_classbuffer_size(cb, 4 + 2))
505 /* skip attribute length */
508 /* number of records */
509 c->innerclasscount = suck_u2(cb);
511 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
514 /* allocate memory for innerclass structure */
515 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
517 for (j = 0; j < c->innerclasscount; j++) {
518 /* The innerclass structure contains a class with an encoded
519 name, its defining scope, its simple name and a bitmask of
522 info = c->innerclass + j;
524 inner.ref = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
525 outer.ref = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
526 name = (utf*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
529 /* If the current inner-class is the currently loaded
530 class check for some special flags. */
532 if (inner.ref->name == c->name) {
533 /* If an inner-class is not a member, its
534 outer-class is NULL. */
536 if (outer.ref != NULL) {
537 c->flags |= ACC_CLASS_MEMBER;
539 /* A member class doesn't have an
540 EnclosingMethod attribute, so set the
541 enclosing-class to be the same as the
544 c->declaringclass = outer;
545 c->enclosingclass = outer;
548 /* If an inner-class is anonymous, its name is
552 c->flags |= ACC_CLASS_ANONYMOUS;
555 info->inner_class = inner;
556 info->outer_class = outer;
561 else if (attribute_name == utf_SourceFile) {
564 if (!class_load_attribute_sourcefile(cb))
567 #if defined(ENABLE_JAVASE)
568 else if (attribute_name == utf_EnclosingMethod) {
569 /* EnclosingMethod */
571 if (!class_load_attribute_enclosingmethod(cb))
574 else if (attribute_name == utf_Signature) {
577 if (!loader_load_attribute_signature(cb, &(c->signature)))
582 #if defined(ENABLE_ANNOTATIONS)
583 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
584 /* RuntimeVisibleAnnotations */
585 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
588 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
589 /* RuntimeInvisibleAnnotations */
590 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
596 /* unknown attribute */
598 if (!loader_skip_attribute_body(cb))
607 /* class_freepool **************************************************************
609 Frees all resources used by this classes Constant Pool.
611 *******************************************************************************/
613 static void class_freecpool(classinfo *c)
619 if (c->cptags && c->cpinfos) {
620 for (idx = 0; idx < c->cpcount; idx++) {
621 tag = c->cptags[idx];
622 info = c->cpinfos[idx];
626 case CONSTANT_Fieldref:
627 case CONSTANT_Methodref:
628 case CONSTANT_InterfaceMethodref:
629 FREE(info, constant_FMIref);
631 case CONSTANT_Integer:
632 FREE(info, constant_integer);
635 FREE(info, constant_float);
638 FREE(info, constant_long);
640 case CONSTANT_Double:
641 FREE(info, constant_double);
643 case CONSTANT_NameAndType:
644 FREE(info, constant_nameandtype);
652 MFREE(c->cptags, u1, c->cpcount);
655 MFREE(c->cpinfos, void*, c->cpcount);
659 /* class_getconstant ***********************************************************
661 Retrieves the value at position 'pos' of the constantpool of a
662 class. If the type of the value is other than 'ctype', an error is
665 *******************************************************************************/
667 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
669 /* check index and type of constantpool entry */
670 /* (pos == 0 is caught by type comparison) */
672 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
673 exceptions_throw_classformaterror(c, "Illegal constant pool index");
677 return c->cpinfos[pos];
681 /* innerclass_getconstant ******************************************************
683 Like class_getconstant, but if cptags is ZERO, null is returned.
685 *******************************************************************************/
687 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
689 /* invalid position in constantpool */
691 if (pos >= c->cpcount) {
692 exceptions_throw_classformaterror(c, "Illegal constant pool index");
696 /* constantpool entry of type 0 */
698 if (c->cptags[pos] == 0)
701 /* check type of constantpool entry */
703 if (c->cptags[pos] != ctype) {
704 exceptions_throw_classformaterror(c, "Illegal constant pool index");
708 return c->cpinfos[pos];
712 /* class_free ******************************************************************
714 Frees all resources used by the class.
716 *******************************************************************************/
718 void class_free(classinfo *c)
725 if (c->interfaces != NULL)
726 MFREE(c->interfaces, classinfo*, c->interfacescount);
729 for (i = 0; i < c->fieldscount; i++)
730 field_free(&(c->fields[i]));
731 MFREE(c->fields, fieldinfo, c->fieldscount);
735 for (i = 0; i < c->methodscount; i++)
736 method_free(&(c->methods[i]));
737 MFREE(c->methods, methodinfo, c->methodscount);
740 if ((v = c->vftbl) != NULL) {
742 mem_free(v->arraydesc,sizeof(arraydescriptor));
744 for (i = 0; i < v->interfacetablelength; i++) {
745 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
747 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
749 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
750 sizeof(methodptr*) * (v->interfacetablelength -
751 (v->interfacetablelength > 0));
752 v = (vftbl_t*) (((methodptr*) v) -
753 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
758 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
760 /* if (c->classvftbl)
761 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
767 /* get_array_class *************************************************************
769 Returns the array class with the given name for the given
770 classloader, or NULL if an exception occurred.
772 Note: This function does eager loading.
774 *******************************************************************************/
776 static classinfo *get_array_class(utf *name,classloader_t *initloader,
777 classloader_t *defloader,bool link)
781 /* lookup this class in the classcache */
782 c = classcache_lookup(initloader,name);
784 c = classcache_lookup_defined(defloader,name);
787 /* we have to create it */
788 c = class_create_classinfo(name);
789 c = load_newly_created_array(c,initloader);
795 assert(c->state & CLASS_LOADED);
796 assert(c->classloader == defloader);
798 if (link && !(c->state & CLASS_LINKED))
802 assert(!link || (c->state & CLASS_LINKED));
808 /* class_array_of **************************************************************
810 Returns an array class with the given component class. The array
811 class is dynamically created if neccessary.
813 *******************************************************************************/
815 classinfo *class_array_of(classinfo *component, bool link)
823 cl = component->classloader;
825 /* Assemble the array class name */
826 namelen = component->name->blength;
828 if (component->name->text[0] == '[') {
829 /* the component is itself an array */
830 namebuf = MNEW(char, namelen + 1);
832 MCOPY(namebuf + 1, component->name->text, char, namelen);
836 /* the component is a non-array class */
837 namebuf = MNEW(char, namelen + 3);
840 MCOPY(namebuf + 2, component->name->text, char, namelen);
841 namebuf[2 + namelen] = ';';
845 u = utf_new(namebuf, namelen);
847 MFREE(namebuf, char, namelen);
849 c = get_array_class(u, cl, cl, link);
855 /* class_multiarray_of *********************************************************
857 Returns an array class with the given dimension and element class.
858 The array class is dynamically created if neccessary.
860 *******************************************************************************/
862 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
869 log_text("Invalid array dimension requested");
873 /* Assemble the array class name */
874 namelen = element->name->blength;
876 if (element->name->text[0] == '[') {
877 /* the element is itself an array */
878 namebuf = MNEW(char, namelen + dim);
879 memcpy(namebuf + dim, element->name->text, namelen);
883 /* the element is a non-array class */
884 namebuf = MNEW(char, namelen + 2 + dim);
886 memcpy(namebuf + dim + 1, element->name->text, namelen);
887 namelen += (2 + dim);
888 namebuf[namelen - 1] = ';';
890 memset(namebuf, '[', dim);
892 utf* u = utf_new(namebuf, namelen);
894 MFREE(namebuf, char, namelen);
896 c = get_array_class(u,
897 element->classloader,
898 element->classloader,
905 /* class_lookup_classref *******************************************************
907 Looks up the constant_classref for a given classname in the classref
911 cls..............the class containing the reference
912 name.............the name of the class refered to
915 a pointer to a constant_classref, or
916 NULL if the reference was not found
918 *******************************************************************************/
920 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
922 constant_classref *ref;
923 extra_classref *xref;
928 assert(!cls->classrefcount || cls->classrefs);
930 /* first search the main classref table */
931 count = cls->classrefcount;
932 ref = cls->classrefs;
933 for (; count; --count, ++ref)
934 if (ref->name == name)
937 /* next try the list of extra classrefs */
938 for (xref = cls->extclassrefs; xref; xref = xref->next) {
939 if (xref->classref.name == name)
940 return &(xref->classref);
948 /* class_get_classref **********************************************************
950 Returns the constant_classref for a given classname.
953 cls..............the class containing the reference
954 name.............the name of the class refered to
957 a pointer to a constant_classref (never NULL)
960 The given name is not checked for validity!
962 *******************************************************************************/
964 constant_classref *class_get_classref(classinfo *cls, utf *name)
966 constant_classref *ref;
967 extra_classref *xref;
972 ref = class_lookup_classref(cls,name);
976 xref = NEW(extra_classref);
977 CLASSREF_INIT(xref->classref,cls,name);
979 xref->next = cls->extclassrefs;
980 cls->extclassrefs = xref;
982 return &(xref->classref);
986 /* class_get_self_classref *****************************************************
988 Returns the constant_classref to the class itself.
991 cls..............the class containing the reference
994 a pointer to a constant_classref (never NULL)
996 *******************************************************************************/
998 constant_classref *class_get_self_classref(classinfo *cls)
1000 /* XXX this should be done in a faster way. Maybe always make */
1001 /* the classref of index 0 a self reference. */
1002 return class_get_classref(cls,cls->name);
1005 /* class_get_classref_multiarray_of ********************************************
1007 Returns an array type reference with the given dimension and element class
1011 dim..............the requested dimension
1012 dim must be in [1;255]. This is NOT checked!
1013 ref..............the component class reference
1016 a pointer to the class reference for the array type
1019 The referer of `ref` is used as the referer for the new classref.
1021 *******************************************************************************/
1023 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1027 constant_classref *cr;
1030 assert(dim >= 1 && dim <= 255);
1032 /* Assemble the array class name */
1033 namelen = ref->name->blength;
1035 if (ref->name->text[0] == '[') {
1036 /* the element is itself an array */
1037 namebuf = MNEW(char, namelen + dim);
1038 memcpy(namebuf + dim, ref->name->text, namelen);
1042 /* the element is a non-array class */
1043 namebuf = MNEW(char, namelen + 2 + dim);
1045 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1046 namelen += (2 + dim);
1047 namebuf[namelen - 1] = ';';
1049 memset(namebuf, '[', dim);
1051 utf* u = utf_new(namebuf, namelen);
1053 MFREE(namebuf, char, namelen);
1055 cr = class_get_classref(ref->referer, u);
1061 /* class_get_classref_component_of *********************************************
1063 Returns the component classref of a given array type reference
1066 ref..............the array type reference
1069 a reference to the component class, or
1070 NULL if `ref` is not an object array type reference
1073 The referer of `ref` is used as the referer for the new classref.
1075 *******************************************************************************/
1077 constant_classref *class_get_classref_component_of(constant_classref *ref)
1084 name = ref->name->text;
1088 namelen = ref->name->blength - 1;
1093 else if (*name != '[') {
1097 return class_get_classref(ref->referer, utf_new(name, namelen));
1101 /* class_findmethod ************************************************************
1103 Searches a 'classinfo' structure for a method having the given name
1104 and descriptor. If descriptor is NULL, it is ignored.
1106 *******************************************************************************/
1108 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1113 for (i = 0; i < c->methodscount; i++) {
1114 m = &(c->methods[i]);
1116 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1124 /* class_resolvemethod *********************************************************
1126 Searches a class and it's super classes for a method.
1128 Superinterfaces are *not* searched.
1130 *******************************************************************************/
1132 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1137 m = class_findmethod(c, name, desc);
1142 /* JVM Specification bug:
1144 It is important NOT to resolve special <init> and <clinit>
1145 methods to super classes or interfaces; yet, this is not
1146 explicited in the specification. Section 5.4.3.3 should be
1147 updated appropriately. */
1149 if (name == utf_init || name == utf_clinit)
1159 /* class_resolveinterfacemethod_intern *****************************************
1161 Internally used helper function. Do not use this directly.
1163 *******************************************************************************/
1165 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1166 utf *name, utf *desc)
1171 /* try to find the method in the class */
1173 m = class_findmethod(c, name, desc);
1178 /* No method found? Try the super interfaces. */
1180 for (i = 0; i < c->interfacescount; i++) {
1181 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1187 /* no method found */
1193 /* class_resolveclassmethod ****************************************************
1195 Resolves a reference from REFERER to a method with NAME and DESC in
1198 If the method cannot be resolved the return value is NULL. If
1199 EXCEPT is true *exceptionptr is set, too.
1201 *******************************************************************************/
1203 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1204 classinfo *referer, bool throwexception)
1210 /* if (c->flags & ACC_INTERFACE) { */
1211 /* if (throwexception) */
1212 /* *exceptionptr = */
1213 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1217 /* try class c and its superclasses */
1221 m = class_resolvemethod(cls, name, desc);
1226 /* Try the super interfaces. */
1228 for (i = 0; i < c->interfacescount; i++) {
1229 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1236 exceptions_throw_nosuchmethoderror(c, name, desc);
1241 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1243 exceptions_throw_abstractmethoderror();
1248 /* XXX check access rights */
1254 /* class_resolveinterfacemethod ************************************************
1256 Resolves a reference from REFERER to a method with NAME and DESC in
1259 If the method cannot be resolved the return value is NULL. If
1260 EXCEPT is true *exceptionptr is set, too.
1262 *******************************************************************************/
1264 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1265 classinfo *referer, bool throwexception)
1269 if (!(c->flags & ACC_INTERFACE)) {
1271 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1276 mi = class_resolveinterfacemethod_intern(c, name, desc);
1281 /* try class java.lang.Object */
1283 mi = class_findmethod(class_java_lang_Object, name, desc);
1289 exceptions_throw_nosuchmethoderror(c, name, desc);
1295 /* class_findfield *************************************************************
1297 Searches for field with specified name and type in a classinfo
1298 structure. If no such field is found NULL is returned.
1300 *******************************************************************************/
1302 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1306 for (i = 0; i < c->fieldscount; i++)
1307 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1308 return &(c->fields[i]);
1310 if (c->super != NULL)
1311 return class_findfield(c->super, name, desc);
1317 /* class_findfield_approx ******************************************************
1319 Searches in 'classinfo'-structure for a field with the specified
1322 *******************************************************************************/
1324 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1326 for (int32_t i = 0; i < c->fieldscount; i++) {
1327 fieldinfo* f = &(c->fields[i]);
1329 if (f->name == name)
1334 exceptions_throw_nosuchfielderror(c, name);
1339 /****************** Function: class_resolvefield_int ***************************
1341 This is an internally used helper function. Do not use this directly.
1343 Tries to resolve a field having the given name and type.
1344 If the field cannot be resolved, NULL is returned.
1346 *******************************************************************************/
1348 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1353 /* search for field in class c */
1355 for (i = 0; i < c->fieldscount; i++) {
1356 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1357 return &(c->fields[i]);
1361 /* Try super interfaces recursively. */
1363 for (i = 0; i < c->interfacescount; i++) {
1364 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1370 /* Try super class. */
1372 if (c->super != NULL)
1373 return class_resolvefield_int(c->super, name, desc);
1381 /********************* Function: class_resolvefield ***************************
1383 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1385 If the field cannot be resolved, an exception is thrown and the
1386 return value is NULL.
1388 *******************************************************************************/
1390 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1394 fi = class_resolvefield_int(c, name, desc);
1397 exceptions_throw_nosuchfielderror(c, name);
1401 /* XXX check access rights */
1407 /* class_issubclass ************************************************************
1409 Checks if sub is a descendant of super.
1411 *******************************************************************************/
1413 bool class_issubclass(classinfo *sub, classinfo *super)
1420 /* We reached java/lang/Object and did not find the requested
1426 /* We found the requested super class. */
1436 /* class_isanysubclass *********************************************************
1438 Checks a subclass relation between two classes. Implemented
1439 interfaces are interpreted as super classes.
1441 Return value: 1 ... sub is subclass of super
1444 *******************************************************************************/
1446 bool class_isanysubclass(classinfo *sub, classinfo *super)
1450 /* This is the trivial case. */
1455 /* Primitive classes are only subclasses of themselves. */
1457 if (class_is_primitive(sub) || class_is_primitive(super))
1460 /* Check for interfaces. */
1462 if (super->flags & ACC_INTERFACE) {
1463 result = (sub->vftbl->interfacetablelength > super->index) &&
1464 (sub->vftbl->interfacetable[-super->index] != NULL);
1467 /* java.lang.Object is the only super class of any
1470 if (sub->flags & ACC_INTERFACE)
1471 return (super == class_java_lang_Object);
1473 #if USES_NEW_SUBTYPE
1474 result = fast_subtype_check(sub->vftbl, super->vftbl);
1476 LOCK_CLASSRENUMBER_LOCK;
1478 uint32_t diffval = sub->vftbl->baseval - super->vftbl->baseval;
1479 result = diffval <= (uint32_t) super->vftbl->diffval;
1481 UNLOCK_CLASSRENUMBER_LOCK;
1489 /* class_is_arraycompatible ****************************************************
1491 Checks if two array type descriptors are assignment compatible.
1494 true .... target = desc is possible
1497 *******************************************************************************/
1499 bool class_is_arraycompatible(arraydescriptor *desc, arraydescriptor *target)
1504 if (desc->arraytype != target->arraytype)
1507 if (desc->arraytype != ARRAYTYPE_OBJECT)
1510 /* {both arrays are arrays of references} */
1512 if (desc->dimension == target->dimension) {
1513 if (!desc->elementvftbl)
1516 /* an array which contains elements of interface types is
1517 allowed to be casted to array of Object (JOWENN) */
1519 if ((desc->elementvftbl->baseval < 0) &&
1520 (target->elementvftbl->baseval == 1))
1523 return class_isanysubclass(desc->elementvftbl->clazz,
1524 target->elementvftbl->clazz);
1527 if (desc->dimension < target->dimension)
1530 /* {desc has higher dimension than target} */
1532 return class_isanysubclass(pseudo_class_Arraystub,
1533 target->elementvftbl->clazz);
1537 /* class_is_assignable_from ****************************************************
1539 Return whether an instance of the "from" class parameter would be
1540 an instance of this class "to" as well.
1547 true .... is assignable
1548 false ... is not assignable
1550 *******************************************************************************/
1552 bool class_is_assignable_from(classinfo *to, classinfo *from)
1554 if (!(to->state & CLASS_LINKED))
1555 if (!link_class(to))
1558 if (!(from->state & CLASS_LINKED))
1559 if (!link_class(from))
1562 /* Decide whether we are dealing with array types or object types. */
1564 if (class_is_array(to) && class_is_array(from))
1565 return class_is_arraycompatible(from->vftbl->arraydesc, to->vftbl->arraydesc);
1567 return class_isanysubclass(from, to);
1571 /* class_is_instance ***********************************************************
1573 Return if the given Java object is an instance of the given class.
1580 true .... is instance
1581 false ... is not instance
1583 *******************************************************************************/
1585 bool class_is_instance(classinfo *c, java_handle_t *h)
1587 if (!(c->state & CLASS_LINKED))
1591 /* Decide whether we are dealing with array types or object types. */
1593 if (class_is_array(c))
1594 return builtin_arrayinstanceof(h, c);
1596 return builtin_instanceof(h, c);
1600 /* class_get_componenttype *****************************************************
1602 Return the component class of the given class. If the given class
1603 is not an array, return NULL.
1605 *******************************************************************************/
1607 classinfo *class_get_componenttype(classinfo *c)
1609 classinfo *component;
1610 arraydescriptor *ad;
1612 /* XXX maybe we could find a way to do this without linking. */
1613 /* This way should be safe and easy, however. */
1615 if (!(c->state & CLASS_LINKED))
1619 ad = c->vftbl->arraydesc;
1624 if (ad->arraytype == ARRAYTYPE_OBJECT)
1625 component = ad->componentvftbl->clazz;
1627 component = Primitive::get_class_by_type(ad->arraytype);
1633 /* class_get_declaredclasses ***************************************************
1635 Return an array of declared classes of the given class.
1637 *******************************************************************************/
1639 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1641 classref_or_classinfo inner;
1642 classref_or_classinfo outer;
1644 int declaredclasscount; /* number of declared classes */
1645 int pos; /* current declared class */
1646 java_handle_objectarray_t *oa; /* array of declared classes */
1650 declaredclasscount = 0;
1652 if (!class_is_primitive(c) && !class_is_array(c)) {
1653 /* Determine number of declared classes. */
1655 for (i = 0; i < c->innerclasscount; i++) {
1656 /* Get outer-class. If the inner-class is not a member
1657 class, the outer-class is NULL. */
1659 outer = c->innerclass[i].outer_class;
1661 if (outer.any == NULL)
1664 /* Check if outer-class is a classref or a real class and
1665 get the class name from the structure. */
1667 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1669 /* Outer class is this class. */
1671 if ((outername == c->name) &&
1672 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1673 declaredclasscount++;
1677 /* Allocate Class[] and check for OOM. */
1679 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1684 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1685 inner = c->innerclass[i].inner_class;
1686 outer = c->innerclass[i].outer_class;
1688 /* Get outer-class. If the inner-class is not a member class,
1689 the outer-class is NULL. */
1691 if (outer.any == NULL)
1694 /* Check if outer_class is a classref or a real class and get
1695 the class name from the structure. */
1697 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1699 /* Outer class is this class. */
1701 if ((outername == c->name) &&
1702 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1704 ic = resolve_classref_or_classinfo_eager(inner, false);
1709 if (!(ic->state & CLASS_LINKED))
1710 if (!link_class(ic))
1713 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1722 * Return an array of declared constructors of the given class.
1724 * @param c class to get the constructors of
1725 * @param publicOnly show only public fields
1727 * @return array of java.lang.reflect.Constructor
1729 #if defined(ENABLE_JAVASE)
1730 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1733 java_handle_objectarray_t* oa;
1738 /* Determine number of constructors. */
1742 for (i = 0; i < c->methodscount; i++) {
1743 m = &(c->methods[i]);
1745 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1746 (m->name == utf_init))
1750 /* Create array of constructors. */
1752 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1757 /* Get the constructors and store them in the array. */
1759 for (i = 0, index = 0; i < c->methodscount; i++) {
1760 m = &(c->methods[i]);
1762 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1763 (m->name == utf_init)) {
1764 // Create a java.lang.reflect.Constructor object.
1766 java_lang_reflect_Constructor rc(m);
1768 /* Store object into array. */
1770 array_objectarray_element_set(oa, index, rc.get_handle());
1780 /* class_get_declaredfields ****************************************************
1782 Return an array of declared fields of the given class.
1785 c ............ class to get the fields of
1786 publicOnly ... show only public fields
1789 array of java.lang.reflect.Field
1791 *******************************************************************************/
1793 #if defined(ENABLE_JAVASE)
1794 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1796 java_handle_objectarray_t *oa;
1802 /* Determine number of fields. */
1806 for (i = 0; i < c->fieldscount; i++)
1807 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1810 /* Create array of fields. */
1812 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1817 /* Get the fields and store them in the array. */
1819 for (i = 0, index = 0; i < c->fieldscount; i++) {
1820 f = &(c->fields[i]);
1822 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1823 // Create a java.lang.reflect.Field object.
1825 java_lang_reflect_Field rf(f);
1827 /* Store object into array. */
1829 array_objectarray_element_set(oa, index, rf.get_handle());
1839 /* class_get_declaredmethods ***************************************************
1841 Return an array of declared methods of the given class.
1844 c ............ class to get the methods of
1845 publicOnly ... show only public methods
1848 array of java.lang.reflect.Method
1850 *******************************************************************************/
1852 #if defined(ENABLE_JAVASE)
1853 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1855 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1856 methodinfo *m; /* the current method to be represented */
1861 /* JOWENN: array classes do not declare methods according to mauve
1862 test. It should be considered, if we should return to my old
1863 clone method overriding instead of declaring it as a member
1866 if (class_is_array(c))
1867 return builtin_anewarray(0, class_java_lang_reflect_Method);
1869 /* Determine number of methods. */
1873 for (i = 0; i < c->methodscount; i++) {
1874 m = &(c->methods[i]);
1876 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1877 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1878 !(m->flags & ACC_MIRANDA))
1882 /* Create array of methods. */
1884 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1889 /* Get the methods and store them in the array. */
1891 for (i = 0, index = 0; i < c->methodscount; i++) {
1892 m = &(c->methods[i]);
1894 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1895 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1896 !(m->flags & ACC_MIRANDA)) {
1897 // Create java.lang.reflect.Method object.
1899 java_lang_reflect_Method rm(m);
1901 /* Store object into array. */
1903 array_objectarray_element_set(oa, index, rm.get_handle());
1913 /* class_get_declaringclass ****************************************************
1915 If the class or interface given is a member of another class,
1916 return the declaring class. For array and primitive classes return
1919 *******************************************************************************/
1921 classinfo *class_get_declaringclass(classinfo *c)
1923 classref_or_classinfo cr;
1926 /* Get declaring class. */
1928 cr = c->declaringclass;
1933 /* Resolve the class if necessary. */
1935 if (IS_CLASSREF(cr)) {
1936 /* dc = resolve_classref_eager(cr.ref); */
1937 dc = resolve_classref_or_classinfo_eager(cr, true);
1942 /* Store the resolved class in the class structure. */
1953 /* class_get_enclosingclass ****************************************************
1955 Return the enclosing class for the given class.
1957 *******************************************************************************/
1959 classinfo *class_get_enclosingclass(classinfo *c)
1961 classref_or_classinfo cr;
1964 /* Get enclosing class. */
1966 cr = c->enclosingclass;
1971 /* Resolve the class if necessary. */
1973 if (IS_CLASSREF(cr)) {
1974 /* ec = resolve_classref_eager(cr.ref); */
1975 ec = resolve_classref_or_classinfo_eager(cr, true);
1980 /* Store the resolved class in the class structure. */
1992 * Return the enclosing constructor as java.lang.reflect.Constructor
1993 * object for the given class.
1995 * @param c class to return the enclosing constructor for
1997 * @return java.lang.reflect.Constructor object of the enclosing
2000 #if defined(ENABLE_JAVASE)
2001 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2005 m = class_get_enclosingmethod_raw(c);
2010 /* Check for <init>. */
2012 if (m->name != utf_init)
2015 // Create a java.lang.reflect.Constructor object.
2017 java_lang_reflect_Constructor rc(m);
2019 return rc.get_handle();
2024 /* class_get_enclosingmethod ***************************************************
2026 Return the enclosing method for the given class.
2029 c ... class to return the enclosing method for
2032 methodinfo of the enclosing method
2034 *******************************************************************************/
2036 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2038 constant_nameandtype *cn;
2042 /* get enclosing class and method */
2044 ec = class_get_enclosingclass(c);
2045 cn = c->enclosingmethod;
2047 /* check for enclosing class and method */
2055 /* find method in enclosing class */
2057 m = class_findmethod(ec, cn->name, cn->descriptor);
2060 exceptions_throw_internalerror("Enclosing method doesn't exist");
2069 * Return the enclosing method as java.lang.reflect.Method object for
2072 * @param c class to return the enclosing method for
2074 * @return java.lang.reflect.Method object of the enclosing method
2076 #if defined(ENABLE_JAVASE)
2077 java_handle_t* class_get_enclosingmethod(classinfo *c)
2081 m = class_get_enclosingmethod_raw(c);
2086 /* check for <init> */
2088 if (m->name == utf_init)
2091 // Create a java.lang.reflect.Method object.
2093 java_lang_reflect_Method rm(m);
2095 return rm.get_handle();
2100 /* class_get_interfaces ********************************************************
2102 Return an array of interfaces of the given class.
2104 *******************************************************************************/
2106 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2109 java_handle_objectarray_t *oa;
2112 if (!(c->state & CLASS_LINKED))
2116 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2121 for (i = 0; i < c->interfacescount; i++) {
2122 ic = c->interfaces[i];
2124 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2131 /* class_get_annotations *******************************************************
2133 Get the unparsed declared annotations in a byte array
2137 c........the class of which the annotations should be returned
2140 The unparsed declared annotations in a byte array
2141 (or NULL if there aren't any).
2143 *******************************************************************************/
2145 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2147 #if defined(ENABLE_ANNOTATIONS)
2148 java_handle_t *annotations; /* unparsed annotations */
2150 LLNI_classinfo_field_get(c, annotations, annotations);
2152 return (java_handle_bytearray_t*)annotations;
2159 /* class_get_modifiers *********************************************************
2161 Get the modifier flags of the given class.
2164 c....the class of which the modifier flags should be returned
2165 ignoreInnerClassesAttrib
2169 *******************************************************************************/
2171 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2173 classref_or_classinfo inner;
2174 classref_or_classinfo outer;
2179 /* default to flags of passed class */
2183 /* if requested we check if passed class is inner class */
2185 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2186 /* search for passed class as inner class */
2188 for (i = 0; i < c->innerclasscount; i++) {
2189 inner = c->innerclass[i].inner_class;
2190 outer = c->innerclass[i].outer_class;
2192 /* Check if inner is a classref or a real class and get
2193 the name of the structure */
2195 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2197 /* innerclass is this class */
2199 if (innername == c->name) {
2200 /* has the class actually an outer class? */
2203 /* return flags got from the outer class file */
2204 flags = c->innerclass[i].flags;
2211 /* remove ACC_SUPER bit from flags */
2213 return flags & ~ACC_SUPER & ACC_CLASS_REFLECT_MASK;
2217 /* class_get_signature *********************************************************
2219 Return the signature of the given class. For array and primitive
2220 classes return NULL.
2222 *******************************************************************************/
2224 #if defined(ENABLE_JAVASE)
2225 utf *class_get_signature(classinfo *c)
2227 /* For array and primitive classes return NULL. */
2229 if (class_is_array(c) || class_is_primitive(c))
2232 return c->signature;
2237 /* class_printflags ************************************************************
2239 Prints flags of a class.
2241 *******************************************************************************/
2243 #if !defined(NDEBUG)
2244 void class_printflags(classinfo *c)
2251 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2252 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2253 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2254 if (c->flags & ACC_STATIC) printf(" STATIC");
2255 if (c->flags & ACC_FINAL) printf(" FINAL");
2256 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2257 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2258 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2259 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2260 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2261 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2266 /* class_print *****************************************************************
2268 Prints classname plus flags.
2270 *******************************************************************************/
2272 #if !defined(NDEBUG)
2273 void class_print(classinfo *c)
2280 utf_display_printable_ascii(c->name);
2281 class_printflags(c);
2286 /* class_classref_print ********************************************************
2288 Prints classname plus referer class.
2290 *******************************************************************************/
2292 #if !defined(NDEBUG)
2293 void class_classref_print(constant_classref *cr)
2300 utf_display_printable_ascii(cr->name);
2303 class_print(cr->referer);
2311 /* class_println ***************************************************************
2313 Prints classname plus flags and new line.
2315 *******************************************************************************/
2317 #if !defined(NDEBUG)
2318 void class_println(classinfo *c)
2326 /* class_classref_println ******************************************************
2328 Prints classname plus referer class and new line.
2330 *******************************************************************************/
2332 #if !defined(NDEBUG)
2333 void class_classref_println(constant_classref *cr)
2335 class_classref_print(cr);
2341 /* class_classref_or_classinfo_print *******************************************
2343 Prints classname plus referer class.
2345 *******************************************************************************/
2347 #if !defined(NDEBUG)
2348 void class_classref_or_classinfo_print(classref_or_classinfo c)
2350 if (c.any == NULL) {
2351 printf("(classref_or_classinfo) NULL");
2355 class_classref_print(c.ref);
2362 /* class_classref_or_classinfo_println *****************************************
2364 Prints classname plus referer class and a newline.
2366 *******************************************************************************/
2368 #if !defined(NDEBUG)
2369 void class_classref_or_classinfo_println(classref_or_classinfo c)
2371 class_classref_or_classinfo_print(c);
2377 /* class_showconstantpool ******************************************************
2379 Dump the constant pool of the given class to stdout.
2381 *******************************************************************************/
2383 #if !defined(NDEBUG)
2384 void class_showconstantpool (classinfo *c)
2389 printf ("---- dump of constant pool ----\n");
2391 for (i=0; i<c->cpcount; i++) {
2392 printf ("#%d: ", (int) i);
2394 e = c -> cpinfos [i];
2397 switch (c -> cptags [i]) {
2398 case CONSTANT_Class:
2399 printf ("Classreference -> ");
2400 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2402 case CONSTANT_Fieldref:
2403 printf ("Fieldref -> ");
2404 field_fieldref_print((constant_FMIref *) e);
2406 case CONSTANT_Methodref:
2407 printf ("Methodref -> ");
2408 method_methodref_print((constant_FMIref *) e);
2410 case CONSTANT_InterfaceMethodref:
2411 printf ("InterfaceMethod -> ");
2412 method_methodref_print((constant_FMIref *) e);
2414 case CONSTANT_String:
2415 printf ("String -> ");
2416 utf_display_printable_ascii ((utf*) e);
2418 case CONSTANT_Integer:
2419 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2421 case CONSTANT_Float:
2422 printf ("Float -> %f", ((constant_float*)e) -> value);
2424 case CONSTANT_Double:
2425 printf ("Double -> %f", ((constant_double*)e) -> value);
2428 printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
2430 case CONSTANT_NameAndType:
2432 constant_nameandtype *cnt = (constant_nameandtype *) e;
2433 printf ("NameAndType: ");
2434 utf_display_printable_ascii (cnt->name);
2436 utf_display_printable_ascii (cnt->descriptor);
2440 printf ("Utf8 -> ");
2441 utf_display_printable_ascii ((utf*) e);
2444 log_text("Invalid type of ConstantPool-Entry");
2452 #endif /* !defined(NDEBUG) */
2455 /* class_showmethods ***********************************************************
2457 Dump info about the fields and methods of the given class to stdout.
2459 *******************************************************************************/
2461 #if !defined(NDEBUG)
2462 void class_showmethods (classinfo *c)
2466 printf("--------- Fields and Methods ----------------\n");
2468 class_printflags(c);
2472 utf_display_printable_ascii(c->name);
2477 utf_display_printable_ascii(c->super->name);
2481 printf("Index: %d\n", c->index);
2483 printf("Interfaces:\n");
2484 for (i = 0; i < c->interfacescount; i++) {
2486 utf_display_printable_ascii(c->interfaces[i]->name);
2487 printf (" (%d)\n", c->interfaces[i]->index);
2490 printf("Fields:\n");
2491 for (i = 0; i < c->fieldscount; i++)
2492 field_println(&(c->fields[i]));
2494 printf("Methods:\n");
2495 for (i = 0; i < c->methodscount; i++) {
2496 methodinfo *m = &(c->methods[i]);
2498 if (!(m->flags & ACC_STATIC))
2499 printf("vftblindex: %d ", m->vftblindex);
2504 printf ("Virtual function table:\n");
2505 for (i = 0; i < c->vftbl->vftbllength; i++)
2506 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2508 #endif /* !defined(NDEBUG) */
2512 * These are local overrides for various environment variables in Emacs.
2513 * Please do not remove this and leave it at the end of the file, where
2514 * Emacs will automagically detect them.
2515 * ---------------------------------------------------------------------
2518 * indent-tabs-mode: t
2522 * vim:noexpandtab:sw=4:ts=4: