1 /* src/vmcore/class.c - class related functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "mm/memory.h"
39 #include "native/llni.h"
41 #include "threads/lock-common.h"
43 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/resolve.h"
51 #include "vm/jit/asmpart.h"
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/linker.h"
56 #include "vmcore/loader.h"
57 #include "vmcore/options.h"
59 #if defined(ENABLE_STATISTICS)
60 # include "vmcore/statistics.h"
63 #include "vmcore/suck.h"
64 #include "vmcore/utf8.h"
67 #if defined(ENABLE_JAVASE)
68 /* We need to define some reflection functions here since we cannot
69 include native/vm/reflect.h as it includes generated header
72 java_object_t *reflect_constructor_new(methodinfo *m);
73 java_object_t *reflect_field_new(fieldinfo *f);
74 java_object_t *reflect_method_new(methodinfo *m);
78 /* global variables ***********************************************************/
80 /* frequently used classes ****************************************************/
82 /* Important system classes. */
84 classinfo *class_java_lang_Object;
85 classinfo *class_java_lang_Class;
86 classinfo *class_java_lang_ClassLoader;
87 classinfo *class_java_lang_Cloneable;
88 classinfo *class_java_lang_SecurityManager;
89 classinfo *class_java_lang_String;
90 classinfo *class_java_lang_System;
91 classinfo *class_java_lang_Thread;
92 classinfo *class_java_lang_ThreadGroup;
93 classinfo *class_java_lang_Throwable;
94 classinfo *class_java_io_Serializable;
96 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
97 classinfo *class_java_lang_VMSystem;
98 classinfo *class_java_lang_VMThread;
99 classinfo *class_java_lang_VMThrowable;
102 /* Important system exceptions. */
104 classinfo *class_java_lang_Exception;
105 classinfo *class_java_lang_ClassNotFoundException;
106 classinfo *class_java_lang_RuntimeException;
108 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
109 classinfo *class_sun_reflect_MagicAccessorImpl;
112 #if defined(ENABLE_JAVASE)
113 classinfo *class_java_lang_Void;
115 classinfo *class_java_lang_Boolean;
116 classinfo *class_java_lang_Byte;
117 classinfo *class_java_lang_Character;
118 classinfo *class_java_lang_Short;
119 classinfo *class_java_lang_Integer;
120 classinfo *class_java_lang_Long;
121 classinfo *class_java_lang_Float;
122 classinfo *class_java_lang_Double;
124 /* some classes which may be used more often */
126 #if defined(ENABLE_JAVASE)
127 classinfo *class_java_lang_StackTraceElement;
128 classinfo *class_java_lang_reflect_Constructor;
129 classinfo *class_java_lang_reflect_Field;
130 classinfo *class_java_lang_reflect_Method;
131 classinfo *class_java_security_PrivilegedAction;
132 classinfo *class_java_util_Vector;
133 classinfo *class_java_util_HashMap;
135 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
136 classinfo *class_java_lang_reflect_VMConstructor;
137 classinfo *class_java_lang_reflect_VMField;
138 classinfo *class_java_lang_reflect_VMMethod;
141 classinfo *arrayclass_java_lang_Object;
143 # if defined(ENABLE_ANNOTATIONS)
144 classinfo *class_sun_reflect_ConstantPool;
145 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
146 classinfo *class_sun_reflect_annotation_AnnotationParser;
151 /* pseudo classes for the typechecker */
153 classinfo *pseudo_class_Arraystub;
154 classinfo *pseudo_class_Null;
155 classinfo *pseudo_class_New;
158 /* class_set_packagename *******************************************************
160 Derive the package name from the class name and store it in the
163 An internal package name consists of the package name plus the
164 trailing '/', e.g. "java/lang/".
166 For classes in the unnamed package, the package name is set to
169 *******************************************************************************/
171 void class_set_packagename(classinfo *c)
176 p = UTF_END(c->name) - 1;
177 start = c->name->text;
179 if (c->name->text[0] == '[') {
180 /* Set packagename of arrays to the element's package. */
182 for (; *start == '['; start++);
184 /* Skip the 'L' in arrays of references. */
190 /* Search for last '/'. */
192 for (; (p > start) && (*p != '/'); --p);
194 /* If we found a '/' we set the package name plus the trailing
195 '/'. Otherwise we set the packagename to NULL. */
198 c->packagename = utf_new(start, p - start + 1);
200 c->packagename = NULL;
204 /* class_create_classinfo ******************************************************
206 Create a new classinfo struct. The class name is set to the given utf *,
207 most other fields are initialized to zero.
209 Note: classname may be NULL. In this case a not-yet-named classinfo is
210 created. The name must be filled in later and class_set_packagename
211 must be called after that.
213 *******************************************************************************/
215 classinfo *class_create_classinfo(utf *classname)
219 #if defined(ENABLE_STATISTICS)
221 size_classinfo += sizeof(classinfo);
224 /* we use a safe name for temporarily unnamed classes */
226 if (classname == NULL)
227 classname = utf_not_named_yet;
231 log_message_utf("Creating class: ", classname);
234 #if !defined(ENABLE_GC_BOEHM)
235 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
236 /*c = NEW(classinfo);
237 MZERO(c, classinfo, 1);*/
239 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
240 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
245 /* Set the header.vftbl of all loaded classes to the one of
246 java.lang.Class, so Java code can use a class as object. */
248 if (class_java_lang_Class != NULL)
249 if (class_java_lang_Class->vftbl != NULL)
250 c->object.header.vftbl = class_java_lang_Class->vftbl;
252 #if defined(ENABLE_JAVASE)
253 /* check if the class is a reference class and flag it */
255 if (classname == utf_java_lang_ref_SoftReference) {
256 c->flags |= ACC_CLASS_REFERENCE_SOFT;
258 else if (classname == utf_java_lang_ref_WeakReference) {
259 c->flags |= ACC_CLASS_REFERENCE_WEAK;
261 else if (classname == utf_java_lang_ref_PhantomReference) {
262 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
266 if (classname != utf_not_named_yet)
267 class_set_packagename(c);
269 LOCK_INIT_OBJECT_LOCK(&c->object.header);
275 /* class_postset_header_vftbl **************************************************
277 Set the header.vftbl of all classes created before java.lang.Class
278 was linked. This is necessary that Java code can use a class as
281 *******************************************************************************/
283 void class_postset_header_vftbl(void)
287 classcache_name_entry *nmen;
288 classcache_class_entry *clsen;
290 assert(class_java_lang_Class);
292 for (slot = 0; slot < hashtable_classcache.size; slot++) {
293 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
295 for (; nmen; nmen = nmen->hashlink) {
296 /* iterate over all class entries */
298 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
301 /* now set the the vftbl */
303 if (c->object.header.vftbl == NULL)
304 c->object.header.vftbl = class_java_lang_Class->vftbl;
310 /* class_define ****************************************************************
312 Calls the loader and defines a class in the VM.
314 *******************************************************************************/
316 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
323 /* check if this class has already been defined */
325 c = classcache_lookup_defined_or_initiated(cl, name);
328 exceptions_throw_linkageerror("duplicate class definition: ", c);
333 /* create a new classinfo struct */
335 c = class_create_classinfo(name);
337 #if defined(ENABLE_STATISTICS)
340 if (opt_getloadingtime)
344 /* build a classbuffer with the given data */
346 cb = NEW(classbuffer);
353 /* preset the defining classloader */
357 /* load the class from this buffer */
359 r = load_class_from_classbuffer(cb);
363 FREE(cb, classbuffer);
365 #if defined(ENABLE_STATISTICS)
368 if (opt_getloadingtime)
373 /* If return value is NULL, we had a problem and the class is
374 not loaded. Now free the allocated memory, otherwise we
375 could run into a DOS. */
382 #if defined(ENABLE_JAVASE)
383 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
384 /* Store the protection domain. */
386 c->protectiondomain = pd;
390 /* Store the newly defined class in the class cache. This call
391 also checks whether a class of the same name has already been
392 defined by the same defining loader, and if so, replaces the
393 newly created class by the one defined earlier. */
395 /* Important: The classinfo given to classcache_store must be
396 fully prepared because another thread may return
397 this pointer after the lookup at to top of this
398 function directly after the class cache lock has
401 c = classcache_store(cl, c, true);
407 /* class_load_attribute_sourcefile *********************************************
409 SourceFile_attribute {
410 u2 attribute_name_index;
415 *******************************************************************************/
417 static bool class_load_attribute_sourcefile(classbuffer *cb)
428 /* check buffer size */
430 if (!suck_check_classbuffer_size(cb, 4 + 2))
433 /* check attribute length */
435 attribute_length = suck_u4(cb);
437 if (attribute_length != 2) {
438 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
442 /* there can be no more than one SourceFile attribute */
444 if (c->sourcefile != NULL) {
445 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
451 sourcefile_index = suck_u2(cb);
452 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
454 if (sourcefile == NULL)
457 /* store sourcefile */
459 c->sourcefile = sourcefile;
465 /* class_load_attribute_enclosingmethod ****************************************
467 EnclosingMethod_attribute {
468 u2 attribute_name_index;
474 *******************************************************************************/
476 #if defined(ENABLE_JAVASE)
477 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
483 classref_or_classinfo cr;
484 constant_nameandtype *cn;
490 /* check buffer size */
492 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
495 /* check attribute length */
497 attribute_length = suck_u4(cb);
499 if (attribute_length != 4) {
500 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
504 /* there can be no more than one EnclosingMethod attribute */
506 if (c->enclosingmethod != NULL) {
507 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
511 /* get class index */
513 class_index = suck_u2(cb);
514 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
516 /* get method index */
518 method_index = suck_u2(cb);
519 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
521 /* store info in classinfo */
523 c->enclosingclass.any = cr.any;
524 c->enclosingmethod = cn;
528 #endif /* defined(ENABLE_JAVASE) */
531 /* class_load_attributes *******************************************************
533 Read attributes from ClassFile.
536 u2 attribute_name_index;
538 u1 info[attribute_length];
541 InnerClasses_attribute {
542 u2 attribute_name_index;
546 *******************************************************************************/
548 bool class_load_attributes(classbuffer *cb)
551 uint16_t attributes_count;
552 uint16_t attribute_name_index;
554 innerclassinfo *info;
555 classref_or_classinfo inner;
556 classref_or_classinfo outer;
563 /* get attributes count */
565 if (!suck_check_classbuffer_size(cb, 2))
568 attributes_count = suck_u2(cb);
570 for (i = 0; i < attributes_count; i++) {
571 /* get attribute name */
573 if (!suck_check_classbuffer_size(cb, 2))
576 attribute_name_index = suck_u2(cb);
578 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
580 if (attribute_name == NULL)
583 if (attribute_name == utf_InnerClasses) {
586 if (c->innerclass != NULL) {
587 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
591 if (!suck_check_classbuffer_size(cb, 4 + 2))
594 /* skip attribute length */
597 /* number of records */
598 c->innerclasscount = suck_u2(cb);
600 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
603 /* allocate memory for innerclass structure */
604 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
606 for (j = 0; j < c->innerclasscount; j++) {
607 /* The innerclass structure contains a class with an encoded
608 name, its defining scope, its simple name and a bitmask of
611 info = c->innerclass + j;
613 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
614 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
615 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
618 /* If the current inner-class is the currently loaded
619 class check for some special flags. */
621 if (inner.ref->name == c->name) {
622 /* If an inner-class is not a member, its
623 outer-class is NULL. */
625 if (outer.ref != NULL) {
626 c->flags |= ACC_CLASS_MEMBER;
628 /* A member class doesn't have an
629 EnclosingMethod attribute, so set the
630 enclosing-class to be the same as the
633 c->declaringclass = outer;
634 c->enclosingclass = outer;
637 /* If an inner-class is anonymous, its name is
641 c->flags |= ACC_CLASS_ANONYMOUS;
644 info->inner_class = inner;
645 info->outer_class = outer;
650 else if (attribute_name == utf_SourceFile) {
653 if (!class_load_attribute_sourcefile(cb))
656 #if defined(ENABLE_JAVASE)
657 else if (attribute_name == utf_EnclosingMethod) {
658 /* EnclosingMethod */
660 if (!class_load_attribute_enclosingmethod(cb))
663 else if (attribute_name == utf_Signature) {
666 if (!loader_load_attribute_signature(cb, &(c->signature)))
671 #if defined(ENABLE_ANNOTATIONS)
672 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
673 /* RuntimeVisibleAnnotations */
674 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
677 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
678 /* RuntimeInvisibleAnnotations */
679 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
685 /* unknown attribute */
687 if (!loader_skip_attribute_body(cb))
696 /* class_freepool **************************************************************
698 Frees all resources used by this classes Constant Pool.
700 *******************************************************************************/
702 static void class_freecpool(classinfo *c)
708 if (c->cptags && c->cpinfos) {
709 for (idx = 0; idx < c->cpcount; idx++) {
710 tag = c->cptags[idx];
711 info = c->cpinfos[idx];
715 case CONSTANT_Fieldref:
716 case CONSTANT_Methodref:
717 case CONSTANT_InterfaceMethodref:
718 FREE(info, constant_FMIref);
720 case CONSTANT_Integer:
721 FREE(info, constant_integer);
724 FREE(info, constant_float);
727 FREE(info, constant_long);
729 case CONSTANT_Double:
730 FREE(info, constant_double);
732 case CONSTANT_NameAndType:
733 FREE(info, constant_nameandtype);
741 MFREE(c->cptags, u1, c->cpcount);
744 MFREE(c->cpinfos, voidptr, c->cpcount);
748 /* class_getconstant ***********************************************************
750 Retrieves the value at position 'pos' of the constantpool of a
751 class. If the type of the value is other than 'ctype', an error is
754 *******************************************************************************/
756 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
758 /* check index and type of constantpool entry */
759 /* (pos == 0 is caught by type comparison) */
761 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
762 exceptions_throw_classformaterror(c, "Illegal constant pool index");
766 return c->cpinfos[pos];
770 /* innerclass_getconstant ******************************************************
772 Like class_getconstant, but if cptags is ZERO, null is returned.
774 *******************************************************************************/
776 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
778 /* invalid position in constantpool */
780 if (pos >= c->cpcount) {
781 exceptions_throw_classformaterror(c, "Illegal constant pool index");
785 /* constantpool entry of type 0 */
787 if (c->cptags[pos] == 0)
790 /* check type of constantpool entry */
792 if (c->cptags[pos] != ctype) {
793 exceptions_throw_classformaterror(c, "Illegal constant pool index");
797 return c->cpinfos[pos];
801 /* class_free ******************************************************************
803 Frees all resources used by the class.
805 *******************************************************************************/
807 void class_free(classinfo *c)
814 if (c->interfaces != NULL)
815 MFREE(c->interfaces, classinfo*, c->interfacescount);
818 for (i = 0; i < c->fieldscount; i++)
819 field_free(&(c->fields[i]));
820 MFREE(c->fields, fieldinfo, c->fieldscount);
824 for (i = 0; i < c->methodscount; i++)
825 method_free(&(c->methods[i]));
826 MFREE(c->methods, methodinfo, c->methodscount);
829 if ((v = c->vftbl) != NULL) {
831 mem_free(v->arraydesc,sizeof(arraydescriptor));
833 for (i = 0; i < v->interfacetablelength; i++) {
834 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
836 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
838 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
839 sizeof(methodptr*) * (v->interfacetablelength -
840 (v->interfacetablelength > 0));
841 v = (vftbl_t*) (((methodptr*) v) -
842 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
847 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
849 /* if (c->classvftbl)
850 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
856 /* get_array_class *************************************************************
858 Returns the array class with the given name for the given
859 classloader, or NULL if an exception occurred.
861 Note: This function does eager loading.
863 *******************************************************************************/
865 static classinfo *get_array_class(utf *name,classloader_t *initloader,
866 classloader_t *defloader,bool link)
870 /* lookup this class in the classcache */
871 c = classcache_lookup(initloader,name);
873 c = classcache_lookup_defined(defloader,name);
876 /* we have to create it */
877 c = class_create_classinfo(name);
878 c = load_newly_created_array(c,initloader);
884 assert(c->state & CLASS_LOADED);
885 assert(c->classloader == defloader);
887 if (link && !(c->state & CLASS_LINKED))
891 assert(!link || (c->state & CLASS_LINKED));
897 /* class_array_of **************************************************************
899 Returns an array class with the given component class. The array
900 class is dynamically created if neccessary.
902 *******************************************************************************/
904 classinfo *class_array_of(classinfo *component, bool link)
913 cl = component->classloader;
917 /* Assemble the array class name */
918 namelen = component->name->blength;
920 if (component->name->text[0] == '[') {
921 /* the component is itself an array */
922 namebuf = DMNEW(char, namelen + 1);
924 MCOPY(namebuf + 1, component->name->text, char, namelen);
928 /* the component is a non-array class */
929 namebuf = DMNEW(char, namelen + 3);
932 MCOPY(namebuf + 2, component->name->text, char, namelen);
933 namebuf[2 + namelen] = ';';
937 u = utf_new(namebuf, namelen);
939 c = get_array_class(u, cl, cl, link);
947 /* class_multiarray_of *********************************************************
949 Returns an array class with the given dimension and element class.
950 The array class is dynamically created if neccessary.
952 *******************************************************************************/
954 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
964 log_text("Invalid array dimension requested");
968 /* Assemble the array class name */
969 namelen = element->name->blength;
971 if (element->name->text[0] == '[') {
972 /* the element is itself an array */
973 namebuf = DMNEW(char, namelen + dim);
974 memcpy(namebuf + dim, element->name->text, namelen);
978 /* the element is a non-array class */
979 namebuf = DMNEW(char, namelen + 2 + dim);
981 memcpy(namebuf + dim + 1, element->name->text, namelen);
982 namelen += (2 + dim);
983 namebuf[namelen - 1] = ';';
985 memset(namebuf, '[', dim);
987 c = get_array_class(utf_new(namebuf, namelen),
988 element->classloader,
989 element->classloader,
998 /* class_lookup_classref *******************************************************
1000 Looks up the constant_classref for a given classname in the classref
1004 cls..............the class containing the reference
1005 name.............the name of the class refered to
1008 a pointer to a constant_classref, or
1009 NULL if the reference was not found
1011 *******************************************************************************/
1013 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
1015 constant_classref *ref;
1016 extra_classref *xref;
1021 assert(!cls->classrefcount || cls->classrefs);
1023 /* first search the main classref table */
1024 count = cls->classrefcount;
1025 ref = cls->classrefs;
1026 for (; count; --count, ++ref)
1027 if (ref->name == name)
1030 /* next try the list of extra classrefs */
1031 for (xref = cls->extclassrefs; xref; xref = xref->next) {
1032 if (xref->classref.name == name)
1033 return &(xref->classref);
1041 /* class_get_classref **********************************************************
1043 Returns the constant_classref for a given classname.
1046 cls..............the class containing the reference
1047 name.............the name of the class refered to
1050 a pointer to a constant_classref (never NULL)
1053 The given name is not checked for validity!
1055 *******************************************************************************/
1057 constant_classref *class_get_classref(classinfo *cls, utf *name)
1059 constant_classref *ref;
1060 extra_classref *xref;
1065 ref = class_lookup_classref(cls,name);
1069 xref = NEW(extra_classref);
1070 CLASSREF_INIT(xref->classref,cls,name);
1072 xref->next = cls->extclassrefs;
1073 cls->extclassrefs = xref;
1075 return &(xref->classref);
1079 /* class_get_self_classref *****************************************************
1081 Returns the constant_classref to the class itself.
1084 cls..............the class containing the reference
1087 a pointer to a constant_classref (never NULL)
1089 *******************************************************************************/
1091 constant_classref *class_get_self_classref(classinfo *cls)
1093 /* XXX this should be done in a faster way. Maybe always make */
1094 /* the classref of index 0 a self reference. */
1095 return class_get_classref(cls,cls->name);
1098 /* class_get_classref_multiarray_of ********************************************
1100 Returns an array type reference with the given dimension and element class
1104 dim..............the requested dimension
1105 dim must be in [1;255]. This is NOT checked!
1106 ref..............the component class reference
1109 a pointer to the class reference for the array type
1112 The referer of `ref` is used as the referer for the new classref.
1114 *******************************************************************************/
1116 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1120 constant_classref *cr;
1124 assert(dim >= 1 && dim <= 255);
1128 /* Assemble the array class name */
1129 namelen = ref->name->blength;
1131 if (ref->name->text[0] == '[') {
1132 /* the element is itself an array */
1133 namebuf = DMNEW(char, namelen + dim);
1134 memcpy(namebuf + dim, ref->name->text, namelen);
1138 /* the element is a non-array class */
1139 namebuf = DMNEW(char, namelen + 2 + dim);
1141 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1142 namelen += (2 + dim);
1143 namebuf[namelen - 1] = ';';
1145 memset(namebuf, '[', dim);
1147 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1155 /* class_get_classref_component_of *********************************************
1157 Returns the component classref of a given array type reference
1160 ref..............the array type reference
1163 a reference to the component class, or
1164 NULL if `ref` is not an object array type reference
1167 The referer of `ref` is used as the referer for the new classref.
1169 *******************************************************************************/
1171 constant_classref *class_get_classref_component_of(constant_classref *ref)
1178 name = ref->name->text;
1182 namelen = ref->name->blength - 1;
1187 else if (*name != '[') {
1191 return class_get_classref(ref->referer, utf_new(name, namelen));
1195 /* class_findmethod ************************************************************
1197 Searches a 'classinfo' structure for a method having the given name
1198 and descriptor. If descriptor is NULL, it is ignored.
1200 *******************************************************************************/
1202 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1207 for (i = 0; i < c->methodscount; i++) {
1208 m = &(c->methods[i]);
1210 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1218 /* class_resolvemethod *********************************************************
1220 Searches a class and it's super classes for a method.
1222 Superinterfaces are *not* searched.
1224 *******************************************************************************/
1226 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1231 m = class_findmethod(c, name, desc);
1236 /* JVM Specification bug:
1238 It is important NOT to resolve special <init> and <clinit>
1239 methods to super classes or interfaces; yet, this is not
1240 explicited in the specification. Section 5.4.3.3 should be
1241 updated appropriately. */
1243 if (name == utf_init || name == utf_clinit)
1253 /* class_resolveinterfacemethod_intern *****************************************
1255 Internally used helper function. Do not use this directly.
1257 *******************************************************************************/
1259 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1260 utf *name, utf *desc)
1265 /* try to find the method in the class */
1267 m = class_findmethod(c, name, desc);
1272 /* No method found? Try the super interfaces. */
1274 for (i = 0; i < c->interfacescount; i++) {
1275 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1281 /* no method found */
1287 /* class_resolveclassmethod ****************************************************
1289 Resolves a reference from REFERER to a method with NAME and DESC in
1292 If the method cannot be resolved the return value is NULL. If
1293 EXCEPT is true *exceptionptr is set, too.
1295 *******************************************************************************/
1297 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1298 classinfo *referer, bool throwexception)
1304 /* if (c->flags & ACC_INTERFACE) { */
1305 /* if (throwexception) */
1306 /* *exceptionptr = */
1307 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1311 /* try class c and its superclasses */
1315 m = class_resolvemethod(cls, name, desc);
1320 /* Try the super interfaces. */
1322 for (i = 0; i < c->interfacescount; i++) {
1323 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1330 exceptions_throw_nosuchmethoderror(c, name, desc);
1335 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1337 exceptions_throw_abstractmethoderror();
1342 /* XXX check access rights */
1348 /* class_resolveinterfacemethod ************************************************
1350 Resolves a reference from REFERER to a method with NAME and DESC in
1353 If the method cannot be resolved the return value is NULL. If
1354 EXCEPT is true *exceptionptr is set, too.
1356 *******************************************************************************/
1358 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1359 classinfo *referer, bool throwexception)
1363 if (!(c->flags & ACC_INTERFACE)) {
1365 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1370 mi = class_resolveinterfacemethod_intern(c, name, desc);
1375 /* try class java.lang.Object */
1377 mi = class_findmethod(class_java_lang_Object, name, desc);
1383 exceptions_throw_nosuchmethoderror(c, name, desc);
1389 /* class_findfield *************************************************************
1391 Searches for field with specified name and type in a classinfo
1392 structure. If no such field is found NULL is returned.
1394 *******************************************************************************/
1396 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1400 for (i = 0; i < c->fieldscount; i++)
1401 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1402 return &(c->fields[i]);
1404 if (c->super != NULL)
1405 return class_findfield(c->super, name, desc);
1411 /* class_findfield_approx ******************************************************
1413 Searches in 'classinfo'-structure for a field with the specified
1416 *******************************************************************************/
1418 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1422 /* get field index */
1424 i = class_findfield_index_by_name(c, name);
1426 /* field was not found, return */
1431 /* return field address */
1433 return &(c->fields[i]);
1437 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1441 for (i = 0; i < c->fieldscount; i++) {
1442 /* compare field names */
1444 if ((c->fields[i].name == name))
1448 /* field was not found, raise exception */
1450 exceptions_throw_nosuchfielderror(c, name);
1456 /****************** Function: class_resolvefield_int ***************************
1458 This is an internally used helper function. Do not use this directly.
1460 Tries to resolve a field having the given name and type.
1461 If the field cannot be resolved, NULL is returned.
1463 *******************************************************************************/
1465 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1470 /* search for field in class c */
1472 for (i = 0; i < c->fieldscount; i++) {
1473 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1474 return &(c->fields[i]);
1478 /* Try super interfaces recursively. */
1480 for (i = 0; i < c->interfacescount; i++) {
1481 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1487 /* Try super class. */
1489 if (c->super != NULL)
1490 return class_resolvefield_int(c->super, name, desc);
1498 /********************* Function: class_resolvefield ***************************
1500 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1502 If the field cannot be resolved the return value is NULL. If EXCEPT is
1503 true *exceptionptr is set, too.
1505 *******************************************************************************/
1507 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1508 classinfo *referer, bool throwexception)
1512 fi = class_resolvefield_int(c, name, desc);
1516 exceptions_throw_nosuchfielderror(c, name);
1521 /* XXX check access rights */
1527 /* class_issubclass ************************************************************
1529 Checks if sub is a descendant of super.
1531 *******************************************************************************/
1533 bool class_issubclass(classinfo *sub, classinfo *super)
1540 /* We reached java/lang/Object and did not find the requested
1546 /* We found the requested super class. */
1556 /* class_isanysubclass *********************************************************
1558 Checks a subclass relation between two classes. Implemented
1559 interfaces are interpreted as super classes.
1561 Return value: 1 ... sub is subclass of super
1564 *******************************************************************************/
1566 bool class_isanysubclass(classinfo *sub, classinfo *super)
1571 /* This is the trivial case. */
1576 /* Primitive classes are only subclasses of themselves. */
1578 if (class_is_primitive(sub) || class_is_primitive(super))
1581 /* Check for interfaces. */
1583 if (super->flags & ACC_INTERFACE) {
1584 result = (sub->vftbl->interfacetablelength > super->index) &&
1585 (sub->vftbl->interfacetable[-super->index] != NULL);
1588 /* java.lang.Object is the only super class of any
1591 if (sub->flags & ACC_INTERFACE)
1592 return (super == class_java_lang_Object);
1594 result = fast_subtype_check(sub->vftbl, super->vftbl);
1601 /* class_is_assignable_from ****************************************************
1603 Return whether an instance of the "from" class parameter would be
1604 an instance of this class "to" as well.
1611 true .... is assignable
1612 false ... is not assignable
1614 *******************************************************************************/
1616 bool class_is_assignable_from(classinfo *to, classinfo *from)
1618 if (!(to->state & CLASS_LINKED))
1619 if (!link_class(to))
1622 if (!(from->state & CLASS_LINKED))
1623 if (!link_class(from))
1626 return class_isanysubclass(from, to);
1630 /* class_is_instance ***********************************************************
1632 Return if the given Java object is an instance of the given class.
1639 true .... is instance
1640 false ... is not instance
1642 *******************************************************************************/
1644 bool class_is_instance(classinfo *c, java_handle_t *h)
1646 if (!(c->state & CLASS_LINKED))
1650 return builtin_instanceof(h, c);
1654 /* class_get_componenttype *****************************************************
1656 Return the component class of the given class. If the given class
1657 is not an array, return NULL.
1659 *******************************************************************************/
1661 classinfo *class_get_componenttype(classinfo *c)
1663 classinfo *component;
1664 arraydescriptor *ad;
1666 /* XXX maybe we could find a way to do this without linking. */
1667 /* This way should be safe and easy, however. */
1669 if (!(c->state & CLASS_LINKED))
1673 ad = c->vftbl->arraydesc;
1678 if (ad->arraytype == ARRAYTYPE_OBJECT)
1679 component = ad->componentvftbl->clazz;
1681 component = primitive_class_get_by_type(ad->arraytype);
1687 /* class_get_declaredclasses ***************************************************
1689 Return an array of declared classes of the given class.
1691 *******************************************************************************/
1693 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1695 classref_or_classinfo inner;
1696 classref_or_classinfo outer;
1698 int declaredclasscount; /* number of declared classes */
1699 int pos; /* current declared class */
1700 java_handle_objectarray_t *oa; /* array of declared classes */
1704 declaredclasscount = 0;
1706 if (!class_is_primitive(c) && !class_is_array(c)) {
1707 /* Determine number of declared classes. */
1709 for (i = 0; i < c->innerclasscount; i++) {
1710 /* Get outer-class. If the inner-class is not a member
1711 class, the outer-class is NULL. */
1713 outer = c->innerclass[i].outer_class;
1715 if (outer.any == NULL)
1718 /* Check if outer-class is a classref or a real class and
1719 get the class name from the structure. */
1721 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1723 /* Outer class is this class. */
1725 if ((outername == c->name) &&
1726 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1727 declaredclasscount++;
1731 /* Allocate Class[] and check for OOM. */
1733 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1738 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1739 inner = c->innerclass[i].inner_class;
1740 outer = c->innerclass[i].outer_class;
1742 /* Get outer-class. If the inner-class is not a member class,
1743 the outer-class is NULL. */
1745 if (outer.any == NULL)
1748 /* Check if outer_class is a classref or a real class and get
1749 the class name from the structure. */
1751 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1753 /* Outer class is this class. */
1755 if ((outername == c->name) &&
1756 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1758 ic = resolve_classref_or_classinfo_eager(inner, false);
1763 if (!(ic->state & CLASS_LINKED))
1764 if (!link_class(ic))
1767 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1776 * Return an array of declared constructors of the given class.
1778 * @param c class to get the constructors of
1779 * @param publicOnly show only public fields
1781 * @return array of java.lang.reflect.Constructor
1783 #if defined(ENABLE_JAVASE)
1784 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1787 java_handle_objectarray_t* oa;
1793 /* Determine number of constructors. */
1797 for (i = 0; i < c->methodscount; i++) {
1798 m = &(c->methods[i]);
1800 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1801 (m->name == utf_init))
1805 /* Create array of constructors. */
1807 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1812 /* Get the constructors and store them in the array. */
1814 for (i = 0, index = 0; i < c->methodscount; i++) {
1815 m = &(c->methods[i]);
1817 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1818 (m->name == utf_init)) {
1819 /* Create Constructor object. This is actualy a
1820 java_lang_reflect_Constructor pointer, but we use a
1821 java_handle_t here, because we don't have the header
1822 available when building vmcore. */
1824 rc = reflect_constructor_new(m);
1826 /* Store object into array. */
1828 array_objectarray_element_set(oa, index, rc);
1838 /* class_get_declaredfields ****************************************************
1840 Return an array of declared fields of the given class.
1843 c ............ class to get the fields of
1844 publicOnly ... show only public fields
1847 array of java.lang.reflect.Field
1849 *******************************************************************************/
1851 #if defined(ENABLE_JAVASE)
1852 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1854 java_handle_objectarray_t *oa;
1861 /* Determine number of fields. */
1865 for (i = 0; i < c->fieldscount; i++)
1866 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1869 /* Create array of fields. */
1871 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1876 /* Get the fields and store them in the array. */
1878 for (i = 0, index = 0; i < c->fieldscount; i++) {
1879 f = &(c->fields[i]);
1881 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1882 /* Create Field object. This is actualy a
1883 java_lang_reflect_Field pointer, but we use a
1884 java_handle_t here, because we don't have the header
1885 available when building vmcore. */
1887 h = reflect_field_new(f);
1889 /* Store object into array. */
1891 array_objectarray_element_set(oa, index, h);
1901 /* class_get_declaredmethods ***************************************************
1903 Return an array of declared methods of the given class.
1906 c ............ class to get the methods of
1907 publicOnly ... show only public methods
1910 array of java.lang.reflect.Method
1912 *******************************************************************************/
1914 #if defined(ENABLE_JAVASE)
1915 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1917 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1918 methodinfo *m; /* the current method to be represented */
1924 /* JOWENN: array classes do not declare methods according to mauve
1925 test. It should be considered, if we should return to my old
1926 clone method overriding instead of declaring it as a member
1929 if (class_is_array(c))
1930 return builtin_anewarray(0, class_java_lang_reflect_Method);
1932 /* Determine number of methods. */
1936 for (i = 0; i < c->methodscount; i++) {
1937 m = &(c->methods[i]);
1939 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1940 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1941 !(m->flags & ACC_MIRANDA))
1945 /* Create array of methods. */
1947 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1952 /* Get the methods and store them in the array. */
1954 for (i = 0, index = 0; i < c->methodscount; i++) {
1955 m = &(c->methods[i]);
1957 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1958 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1959 !(m->flags & ACC_MIRANDA)) {
1960 /* Create method object. This is actualy a
1961 java_lang_reflect_Method pointer, but we use a
1962 java_handle_t here, because we don't have the header
1963 available when building vmcore. */
1965 h = reflect_method_new(m);
1967 /* Store object into array. */
1969 array_objectarray_element_set(oa, index, h);
1979 /* class_get_declaringclass ****************************************************
1981 If the class or interface given is a member of another class,
1982 return the declaring class. For array and primitive classes return
1985 *******************************************************************************/
1987 classinfo *class_get_declaringclass(classinfo *c)
1989 classref_or_classinfo cr;
1992 /* Get declaring class. */
1994 cr = c->declaringclass;
1999 /* Resolve the class if necessary. */
2001 if (IS_CLASSREF(cr)) {
2002 /* dc = resolve_classref_eager(cr.ref); */
2003 dc = resolve_classref_or_classinfo_eager(cr, true);
2008 /* Store the resolved class in the class structure. */
2019 /* class_get_enclosingclass ****************************************************
2021 Return the enclosing class for the given class.
2023 *******************************************************************************/
2025 classinfo *class_get_enclosingclass(classinfo *c)
2027 classref_or_classinfo cr;
2030 /* Get enclosing class. */
2032 cr = c->enclosingclass;
2037 /* Resolve the class if necessary. */
2039 if (IS_CLASSREF(cr)) {
2040 /* ec = resolve_classref_eager(cr.ref); */
2041 ec = resolve_classref_or_classinfo_eager(cr, true);
2046 /* Store the resolved class in the class structure. */
2058 * Return the enclosing constructor as java.lang.reflect.Constructor
2059 * object for the given class.
2061 * @param c class to return the enclosing constructor for
2063 * @return java.lang.reflect.Constructor object of the enclosing
2066 #if defined(ENABLE_JAVASE)
2067 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2072 m = class_get_enclosingmethod_raw(c);
2077 /* Check for <init>. */
2079 if (m->name != utf_init)
2082 /* Create Constructor object. */
2084 rc = reflect_constructor_new(m);
2091 /* class_get_enclosingmethod ***************************************************
2093 Return the enclosing method for the given class.
2096 c ... class to return the enclosing method for
2099 methodinfo of the enclosing method
2101 *******************************************************************************/
2103 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2105 constant_nameandtype *cn;
2109 /* get enclosing class and method */
2111 ec = class_get_enclosingclass(c);
2112 cn = c->enclosingmethod;
2114 /* check for enclosing class and method */
2122 /* find method in enclosing class */
2124 m = class_findmethod(ec, cn->name, cn->descriptor);
2127 exceptions_throw_internalerror("Enclosing method doesn't exist");
2136 * Return the enclosing method as java.lang.reflect.Method object for
2139 * @param c class to return the enclosing method for
2141 * @return java.lang.reflect.Method object of the enclosing method
2143 #if defined(ENABLE_JAVASE)
2144 java_handle_t* class_get_enclosingmethod(classinfo *c)
2149 m = class_get_enclosingmethod_raw(c);
2154 /* check for <init> */
2156 if (m->name == utf_init)
2159 /* create java.lang.reflect.Method object */
2161 rm = reflect_method_new(m);
2168 /* class_get_interfaces ********************************************************
2170 Return an array of interfaces of the given class.
2172 *******************************************************************************/
2174 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2177 java_handle_objectarray_t *oa;
2180 if (!(c->state & CLASS_LINKED))
2184 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2189 for (i = 0; i < c->interfacescount; i++) {
2190 ic = c->interfaces[i];
2192 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2199 /* class_get_annotations *******************************************************
2201 Get the unparsed declared annotations in a byte array
2205 c........the class of which the annotations should be returned
2208 The unparsed declared annotations in a byte array
2209 (or NULL if there aren't any).
2211 *******************************************************************************/
2213 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2215 #if defined(ENABLE_ANNOTATIONS)
2216 java_handle_t *annotations; /* unparsed annotations */
2218 LLNI_classinfo_field_get(c, annotations, annotations);
2220 return (java_handle_bytearray_t*)annotations;
2227 /* class_get_modifiers *********************************************************
2229 Get the modifier flags of the given class.
2232 c....the class of which the modifier flags should be returned
2233 ignoreInnerClassesAttrib
2237 *******************************************************************************/
2239 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2241 classref_or_classinfo inner;
2242 classref_or_classinfo outer;
2246 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2247 /* search for passed class as inner class */
2249 for (i = 0; i < c->innerclasscount; i++) {
2250 inner = c->innerclass[i].inner_class;
2251 outer = c->innerclass[i].outer_class;
2253 /* Check if inner is a classref or a real class and get
2254 the name of the structure */
2256 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2258 /* innerclass is this class */
2260 if (innername == c->name) {
2261 /* has the class actually an outer class? */
2264 /* return flags got from the outer class file */
2265 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2267 return c->flags & ACC_CLASS_REFLECT_MASK;
2272 /* passed class is no inner class or it was not requested */
2274 return c->flags & ACC_CLASS_REFLECT_MASK;
2278 /* class_get_signature *********************************************************
2280 Return the signature of the given class. For array and primitive
2281 classes return NULL.
2283 *******************************************************************************/
2285 #if defined(ENABLE_JAVASE)
2286 utf *class_get_signature(classinfo *c)
2288 /* For array and primitive classes return NULL. */
2290 if (class_is_array(c) || class_is_primitive(c))
2293 return c->signature;
2298 /* class_printflags ************************************************************
2300 Prints flags of a class.
2302 *******************************************************************************/
2304 #if !defined(NDEBUG)
2305 void class_printflags(classinfo *c)
2312 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2313 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2314 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2315 if (c->flags & ACC_STATIC) printf(" STATIC");
2316 if (c->flags & ACC_FINAL) printf(" FINAL");
2317 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2318 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2319 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2320 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2321 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2322 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2327 /* class_print *****************************************************************
2329 Prints classname plus flags.
2331 *******************************************************************************/
2333 #if !defined(NDEBUG)
2334 void class_print(classinfo *c)
2341 utf_display_printable_ascii(c->name);
2342 class_printflags(c);
2347 /* class_classref_print ********************************************************
2349 Prints classname plus referer class.
2351 *******************************************************************************/
2353 #if !defined(NDEBUG)
2354 void class_classref_print(constant_classref *cr)
2361 utf_display_printable_ascii(cr->name);
2364 class_print(cr->referer);
2372 /* class_println ***************************************************************
2374 Prints classname plus flags and new line.
2376 *******************************************************************************/
2378 #if !defined(NDEBUG)
2379 void class_println(classinfo *c)
2387 /* class_classref_println ******************************************************
2389 Prints classname plus referer class and new line.
2391 *******************************************************************************/
2393 #if !defined(NDEBUG)
2394 void class_classref_println(constant_classref *cr)
2396 class_classref_print(cr);
2402 /* class_classref_or_classinfo_print *******************************************
2404 Prints classname plus referer class.
2406 *******************************************************************************/
2408 #if !defined(NDEBUG)
2409 void class_classref_or_classinfo_print(classref_or_classinfo c)
2411 if (c.any == NULL) {
2412 printf("(classref_or_classinfo) NULL");
2416 class_classref_print(c.ref);
2423 /* class_classref_or_classinfo_println *****************************************
2425 Prints classname plus referer class and a newline.
2427 *******************************************************************************/
2429 #if !defined(NDEBUG)
2430 void class_classref_or_classinfo_println(classref_or_classinfo c)
2432 class_classref_or_classinfo_print(c);
2438 /* class_showconstantpool ******************************************************
2440 Dump the constant pool of the given class to stdout.
2442 *******************************************************************************/
2444 #if !defined(NDEBUG)
2445 void class_showconstantpool (classinfo *c)
2450 printf ("---- dump of constant pool ----\n");
2452 for (i=0; i<c->cpcount; i++) {
2453 printf ("#%d: ", (int) i);
2455 e = c -> cpinfos [i];
2458 switch (c -> cptags [i]) {
2459 case CONSTANT_Class:
2460 printf ("Classreference -> ");
2461 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2463 case CONSTANT_Fieldref:
2464 printf ("Fieldref -> ");
2465 field_fieldref_print((constant_FMIref *) e);
2467 case CONSTANT_Methodref:
2468 printf ("Methodref -> ");
2469 method_methodref_print((constant_FMIref *) e);
2471 case CONSTANT_InterfaceMethodref:
2472 printf ("InterfaceMethod -> ");
2473 method_methodref_print((constant_FMIref *) e);
2475 case CONSTANT_String:
2476 printf ("String -> ");
2477 utf_display_printable_ascii (e);
2479 case CONSTANT_Integer:
2480 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2482 case CONSTANT_Float:
2483 printf ("Float -> %f", ((constant_float*)e) -> value);
2485 case CONSTANT_Double:
2486 printf ("Double -> %f", ((constant_double*)e) -> value);
2490 u8 v = ((constant_long*)e) -> value;
2492 printf ("Long -> %ld", (long int) v);
2494 printf ("Long -> HI: %ld, LO: %ld\n",
2495 (long int) v.high, (long int) v.low);
2499 case CONSTANT_NameAndType:
2501 constant_nameandtype *cnt = e;
2502 printf ("NameAndType: ");
2503 utf_display_printable_ascii (cnt->name);
2505 utf_display_printable_ascii (cnt->descriptor);
2509 printf ("Utf8 -> ");
2510 utf_display_printable_ascii (e);
2513 log_text("Invalid type of ConstantPool-Entry");
2521 #endif /* !defined(NDEBUG) */
2524 /* class_showmethods ***********************************************************
2526 Dump info about the fields and methods of the given class to stdout.
2528 *******************************************************************************/
2530 #if !defined(NDEBUG)
2531 void class_showmethods (classinfo *c)
2535 printf("--------- Fields and Methods ----------------\n");
2537 class_printflags(c);
2541 utf_display_printable_ascii(c->name);
2546 utf_display_printable_ascii(c->super->name);
2550 printf("Index: %d\n", c->index);
2552 printf("Interfaces:\n");
2553 for (i = 0; i < c->interfacescount; i++) {
2555 utf_display_printable_ascii(c->interfaces[i]->name);
2556 printf (" (%d)\n", c->interfaces[i]->index);
2559 printf("Fields:\n");
2560 for (i = 0; i < c->fieldscount; i++)
2561 field_println(&(c->fields[i]));
2563 printf("Methods:\n");
2564 for (i = 0; i < c->methodscount; i++) {
2565 methodinfo *m = &(c->methods[i]);
2567 if (!(m->flags & ACC_STATIC))
2568 printf("vftblindex: %d ", m->vftblindex);
2573 printf ("Virtual function table:\n");
2574 for (i = 0; i < c->vftbl->vftbllength; i++)
2575 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2577 #endif /* !defined(NDEBUG) */
2581 * These are local overrides for various environment variables in Emacs.
2582 * Please do not remove this and leave it at the end of the file, where
2583 * Emacs will automagically detect them.
2584 * ---------------------------------------------------------------------
2587 * indent-tabs-mode: t
2591 * vim:noexpandtab:sw=4:ts=4: