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_CLASSPATH_GNU)
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_CLASSPATH_SUN)
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_CLASSPATH_GNU)
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_CLASSPATH_GNU)
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_CLASSPATH_SUN)
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 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1596 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1597 result = diffval <= (uint32_t) super->vftbl->diffval;
1599 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1606 /* class_is_assignable_from ****************************************************
1608 Return whether an instance of the "from" class parameter would be
1609 an instance of this class "to" as well.
1616 true .... is assignable
1617 false ... is not assignable
1619 *******************************************************************************/
1621 bool class_is_assignable_from(classinfo *to, classinfo *from)
1623 if (!(to->state & CLASS_LINKED))
1624 if (!link_class(to))
1627 if (!(from->state & CLASS_LINKED))
1628 if (!link_class(from))
1631 return class_isanysubclass(from, to);
1635 /* class_is_instance ***********************************************************
1637 Return if the given Java object is an instance of the given class.
1644 true .... is instance
1645 false ... is not instance
1647 *******************************************************************************/
1649 bool class_is_instance(classinfo *c, java_handle_t *h)
1651 if (!(c->state & CLASS_LINKED))
1655 return builtin_instanceof(h, c);
1659 /* class_get_componenttype *****************************************************
1661 Return the component class of the given class. If the given class
1662 is not an array, return NULL.
1664 *******************************************************************************/
1666 classinfo *class_get_componenttype(classinfo *c)
1668 classinfo *component;
1669 arraydescriptor *ad;
1671 /* XXX maybe we could find a way to do this without linking. */
1672 /* This way should be safe and easy, however. */
1674 if (!(c->state & CLASS_LINKED))
1678 ad = c->vftbl->arraydesc;
1683 if (ad->arraytype == ARRAYTYPE_OBJECT)
1684 component = ad->componentvftbl->clazz;
1686 component = primitive_class_get_by_type(ad->arraytype);
1692 /* class_get_declaredclasses ***************************************************
1694 Return an array of declared classes of the given class.
1696 *******************************************************************************/
1698 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1700 classref_or_classinfo inner;
1701 classref_or_classinfo outer;
1703 int declaredclasscount; /* number of declared classes */
1704 int pos; /* current declared class */
1705 java_handle_objectarray_t *oa; /* array of declared classes */
1709 declaredclasscount = 0;
1711 if (!class_is_primitive(c) && !class_is_array(c)) {
1712 /* Determine number of declared classes. */
1714 for (i = 0; i < c->innerclasscount; i++) {
1715 /* Get outer-class. If the inner-class is not a member
1716 class, the outer-class is NULL. */
1718 outer = c->innerclass[i].outer_class;
1720 if (outer.any == NULL)
1723 /* Check if outer-class is a classref or a real class and
1724 get the class name from the structure. */
1726 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1728 /* Outer class is this class. */
1730 if ((outername == c->name) &&
1731 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1732 declaredclasscount++;
1736 /* Allocate Class[] and check for OOM. */
1738 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1743 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1744 inner = c->innerclass[i].inner_class;
1745 outer = c->innerclass[i].outer_class;
1747 /* Get outer-class. If the inner-class is not a member class,
1748 the outer-class is NULL. */
1750 if (outer.any == NULL)
1753 /* Check if outer_class is a classref or a real class and get
1754 the class name from the structure. */
1756 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1758 /* Outer class is this class. */
1760 if ((outername == c->name) &&
1761 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1763 ic = resolve_classref_or_classinfo_eager(inner, false);
1768 if (!(ic->state & CLASS_LINKED))
1769 if (!link_class(ic))
1772 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1781 * Return an array of declared constructors of the given class.
1783 * @param c class to get the constructors of
1784 * @param publicOnly show only public fields
1786 * @return array of java.lang.reflect.Constructor
1788 #if defined(ENABLE_JAVASE)
1789 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1792 java_handle_objectarray_t* oa;
1798 /* Determine number of constructors. */
1802 for (i = 0; i < c->methodscount; i++) {
1803 m = &(c->methods[i]);
1805 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1806 (m->name == utf_init))
1810 /* Create array of constructors. */
1812 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1817 /* Get the constructors and store them in the array. */
1819 for (i = 0, index = 0; i < c->methodscount; i++) {
1820 m = &(c->methods[i]);
1822 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1823 (m->name == utf_init)) {
1824 /* Create Constructor object. This is actualy a
1825 java_lang_reflect_Constructor pointer, but we use a
1826 java_handle_t here, because we don't have the header
1827 available when building vmcore. */
1829 rc = reflect_constructor_new(m);
1831 /* Store object into array. */
1833 array_objectarray_element_set(oa, index, rc);
1843 /* class_get_declaredfields ****************************************************
1845 Return an array of declared fields of the given class.
1848 c ............ class to get the fields of
1849 publicOnly ... show only public fields
1852 array of java.lang.reflect.Field
1854 *******************************************************************************/
1856 #if defined(ENABLE_JAVASE)
1857 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1859 java_handle_objectarray_t *oa;
1866 /* Determine number of fields. */
1870 for (i = 0; i < c->fieldscount; i++)
1871 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1874 /* Create array of fields. */
1876 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1881 /* Get the fields and store them in the array. */
1883 for (i = 0, index = 0; i < c->fieldscount; i++) {
1884 f = &(c->fields[i]);
1886 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1887 /* Create Field object. This is actualy a
1888 java_lang_reflect_Field pointer, but we use a
1889 java_handle_t here, because we don't have the header
1890 available when building vmcore. */
1892 h = reflect_field_new(f);
1894 /* Store object into array. */
1896 array_objectarray_element_set(oa, index, h);
1906 /* class_get_declaredmethods ***************************************************
1908 Return an array of declared methods of the given class.
1911 c ............ class to get the methods of
1912 publicOnly ... show only public methods
1915 array of java.lang.reflect.Method
1917 *******************************************************************************/
1919 #if defined(ENABLE_JAVASE)
1920 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1922 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1923 methodinfo *m; /* the current method to be represented */
1929 /* JOWENN: array classes do not declare methods according to mauve
1930 test. It should be considered, if we should return to my old
1931 clone method overriding instead of declaring it as a member
1934 if (class_is_array(c))
1935 return builtin_anewarray(0, class_java_lang_reflect_Method);
1937 /* Determine number of methods. */
1941 for (i = 0; i < c->methodscount; i++) {
1942 m = &(c->methods[i]);
1944 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1945 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1946 !(m->flags & ACC_MIRANDA))
1950 /* Create array of methods. */
1952 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1957 /* Get the methods and store them in the array. */
1959 for (i = 0, index = 0; i < c->methodscount; i++) {
1960 m = &(c->methods[i]);
1962 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1963 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1964 !(m->flags & ACC_MIRANDA)) {
1965 /* Create method object. This is actualy a
1966 java_lang_reflect_Method pointer, but we use a
1967 java_handle_t here, because we don't have the header
1968 available when building vmcore. */
1970 h = reflect_method_new(m);
1972 /* Store object into array. */
1974 array_objectarray_element_set(oa, index, h);
1984 /* class_get_declaringclass ****************************************************
1986 If the class or interface given is a member of another class,
1987 return the declaring class. For array and primitive classes return
1990 *******************************************************************************/
1992 classinfo *class_get_declaringclass(classinfo *c)
1994 classref_or_classinfo cr;
1997 /* Get declaring class. */
1999 cr = c->declaringclass;
2004 /* Resolve the class if necessary. */
2006 if (IS_CLASSREF(cr)) {
2007 /* dc = resolve_classref_eager(cr.ref); */
2008 dc = resolve_classref_or_classinfo_eager(cr, true);
2013 /* Store the resolved class in the class structure. */
2024 /* class_get_enclosingclass ****************************************************
2026 Return the enclosing class for the given class.
2028 *******************************************************************************/
2030 classinfo *class_get_enclosingclass(classinfo *c)
2032 classref_or_classinfo cr;
2035 /* Get enclosing class. */
2037 cr = c->enclosingclass;
2042 /* Resolve the class if necessary. */
2044 if (IS_CLASSREF(cr)) {
2045 /* ec = resolve_classref_eager(cr.ref); */
2046 ec = resolve_classref_or_classinfo_eager(cr, true);
2051 /* Store the resolved class in the class structure. */
2063 * Return the enclosing constructor as java.lang.reflect.Constructor
2064 * object for the given class.
2066 * @param c class to return the enclosing constructor for
2068 * @return java.lang.reflect.Constructor object of the enclosing
2071 #if defined(ENABLE_JAVASE)
2072 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2077 m = class_get_enclosingmethod_raw(c);
2082 /* Check for <init>. */
2084 if (m->name != utf_init)
2087 /* Create Constructor object. */
2089 rc = reflect_constructor_new(m);
2096 /* class_get_enclosingmethod ***************************************************
2098 Return the enclosing method for the given class.
2101 c ... class to return the enclosing method for
2104 methodinfo of the enclosing method
2106 *******************************************************************************/
2108 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2110 constant_nameandtype *cn;
2114 /* get enclosing class and method */
2116 ec = class_get_enclosingclass(c);
2117 cn = c->enclosingmethod;
2119 /* check for enclosing class and method */
2127 /* find method in enclosing class */
2129 m = class_findmethod(ec, cn->name, cn->descriptor);
2132 exceptions_throw_internalerror("Enclosing method doesn't exist");
2141 * Return the enclosing method as java.lang.reflect.Method object for
2144 * @param c class to return the enclosing method for
2146 * @return java.lang.reflect.Method object of the enclosing method
2148 #if defined(ENABLE_JAVASE)
2149 java_handle_t* class_get_enclosingmethod(classinfo *c)
2154 m = class_get_enclosingmethod_raw(c);
2159 /* check for <init> */
2161 if (m->name == utf_init)
2164 /* create java.lang.reflect.Method object */
2166 rm = reflect_method_new(m);
2173 /* class_get_interfaces ********************************************************
2175 Return an array of interfaces of the given class.
2177 *******************************************************************************/
2179 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2182 java_handle_objectarray_t *oa;
2185 if (!(c->state & CLASS_LINKED))
2189 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2194 for (i = 0; i < c->interfacescount; i++) {
2195 ic = c->interfaces[i];
2197 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2204 /* class_get_annotations *******************************************************
2206 Get the unparsed declared annotations in a byte array
2210 c........the class of which the annotations should be returned
2213 The unparsed declared annotations in a byte array
2214 (or NULL if there aren't any).
2216 *******************************************************************************/
2218 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2220 #if defined(ENABLE_ANNOTATIONS)
2221 java_handle_t *annotations; /* unparsed annotations */
2223 LLNI_classinfo_field_get(c, annotations, annotations);
2225 return (java_handle_bytearray_t*)annotations;
2232 /* class_get_modifiers *********************************************************
2234 Get the modifier flags of the given class.
2237 c....the class of which the modifier flags should be returned
2238 ignoreInnerClassesAttrib
2242 *******************************************************************************/
2244 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2246 classref_or_classinfo inner;
2247 classref_or_classinfo outer;
2251 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2252 /* search for passed class as inner class */
2254 for (i = 0; i < c->innerclasscount; i++) {
2255 inner = c->innerclass[i].inner_class;
2256 outer = c->innerclass[i].outer_class;
2258 /* Check if inner is a classref or a real class and get
2259 the name of the structure */
2261 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2263 /* innerclass is this class */
2265 if (innername == c->name) {
2266 /* has the class actually an outer class? */
2269 /* return flags got from the outer class file */
2270 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2272 return c->flags & ACC_CLASS_REFLECT_MASK;
2277 /* passed class is no inner class or it was not requested */
2279 return c->flags & ACC_CLASS_REFLECT_MASK;
2283 /* class_get_signature *********************************************************
2285 Return the signature of the given class. For array and primitive
2286 classes return NULL.
2288 *******************************************************************************/
2290 #if defined(ENABLE_JAVASE)
2291 utf *class_get_signature(classinfo *c)
2293 /* For array and primitive classes return NULL. */
2295 if (class_is_array(c) || class_is_primitive(c))
2298 return c->signature;
2303 /* class_printflags ************************************************************
2305 Prints flags of a class.
2307 *******************************************************************************/
2309 #if !defined(NDEBUG)
2310 void class_printflags(classinfo *c)
2317 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2318 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2319 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2320 if (c->flags & ACC_STATIC) printf(" STATIC");
2321 if (c->flags & ACC_FINAL) printf(" FINAL");
2322 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2323 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2324 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2325 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2326 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2327 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2332 /* class_print *****************************************************************
2334 Prints classname plus flags.
2336 *******************************************************************************/
2338 #if !defined(NDEBUG)
2339 void class_print(classinfo *c)
2346 utf_display_printable_ascii(c->name);
2347 class_printflags(c);
2352 /* class_classref_print ********************************************************
2354 Prints classname plus referer class.
2356 *******************************************************************************/
2358 #if !defined(NDEBUG)
2359 void class_classref_print(constant_classref *cr)
2366 utf_display_printable_ascii(cr->name);
2369 class_print(cr->referer);
2377 /* class_println ***************************************************************
2379 Prints classname plus flags and new line.
2381 *******************************************************************************/
2383 #if !defined(NDEBUG)
2384 void class_println(classinfo *c)
2392 /* class_classref_println ******************************************************
2394 Prints classname plus referer class and new line.
2396 *******************************************************************************/
2398 #if !defined(NDEBUG)
2399 void class_classref_println(constant_classref *cr)
2401 class_classref_print(cr);
2407 /* class_classref_or_classinfo_print *******************************************
2409 Prints classname plus referer class.
2411 *******************************************************************************/
2413 #if !defined(NDEBUG)
2414 void class_classref_or_classinfo_print(classref_or_classinfo c)
2416 if (c.any == NULL) {
2417 printf("(classref_or_classinfo) NULL");
2421 class_classref_print(c.ref);
2428 /* class_classref_or_classinfo_println *****************************************
2430 Prints classname plus referer class and a newline.
2432 *******************************************************************************/
2434 #if !defined(NDEBUG)
2435 void class_classref_or_classinfo_println(classref_or_classinfo c)
2437 class_classref_or_classinfo_print(c);
2443 /* class_showconstantpool ******************************************************
2445 Dump the constant pool of the given class to stdout.
2447 *******************************************************************************/
2449 #if !defined(NDEBUG)
2450 void class_showconstantpool (classinfo *c)
2455 printf ("---- dump of constant pool ----\n");
2457 for (i=0; i<c->cpcount; i++) {
2458 printf ("#%d: ", (int) i);
2460 e = c -> cpinfos [i];
2463 switch (c -> cptags [i]) {
2464 case CONSTANT_Class:
2465 printf ("Classreference -> ");
2466 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2468 case CONSTANT_Fieldref:
2469 printf ("Fieldref -> ");
2470 field_fieldref_print((constant_FMIref *) e);
2472 case CONSTANT_Methodref:
2473 printf ("Methodref -> ");
2474 method_methodref_print((constant_FMIref *) e);
2476 case CONSTANT_InterfaceMethodref:
2477 printf ("InterfaceMethod -> ");
2478 method_methodref_print((constant_FMIref *) e);
2480 case CONSTANT_String:
2481 printf ("String -> ");
2482 utf_display_printable_ascii (e);
2484 case CONSTANT_Integer:
2485 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2487 case CONSTANT_Float:
2488 printf ("Float -> %f", ((constant_float*)e) -> value);
2490 case CONSTANT_Double:
2491 printf ("Double -> %f", ((constant_double*)e) -> value);
2495 u8 v = ((constant_long*)e) -> value;
2497 printf ("Long -> %ld", (long int) v);
2499 printf ("Long -> HI: %ld, LO: %ld\n",
2500 (long int) v.high, (long int) v.low);
2504 case CONSTANT_NameAndType:
2506 constant_nameandtype *cnt = e;
2507 printf ("NameAndType: ");
2508 utf_display_printable_ascii (cnt->name);
2510 utf_display_printable_ascii (cnt->descriptor);
2514 printf ("Utf8 -> ");
2515 utf_display_printable_ascii (e);
2518 log_text("Invalid type of ConstantPool-Entry");
2526 #endif /* !defined(NDEBUG) */
2529 /* class_showmethods ***********************************************************
2531 Dump info about the fields and methods of the given class to stdout.
2533 *******************************************************************************/
2535 #if !defined(NDEBUG)
2536 void class_showmethods (classinfo *c)
2540 printf("--------- Fields and Methods ----------------\n");
2542 class_printflags(c);
2546 utf_display_printable_ascii(c->name);
2551 utf_display_printable_ascii(c->super->name);
2555 printf("Index: %d\n", c->index);
2557 printf("Interfaces:\n");
2558 for (i = 0; i < c->interfacescount; i++) {
2560 utf_display_printable_ascii(c->interfaces[i]->name);
2561 printf (" (%d)\n", c->interfaces[i]->index);
2564 printf("Fields:\n");
2565 for (i = 0; i < c->fieldscount; i++)
2566 field_println(&(c->fields[i]));
2568 printf("Methods:\n");
2569 for (i = 0; i < c->methodscount; i++) {
2570 methodinfo *m = &(c->methods[i]);
2572 if (!(m->flags & ACC_STATIC))
2573 printf("vftblindex: %d ", m->vftblindex);
2578 printf ("Virtual function table:\n");
2579 for (i = 0; i < c->vftbl->vftbllength; i++)
2580 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2582 #endif /* !defined(NDEBUG) */
2586 * These are local overrides for various environment variables in Emacs.
2587 * Please do not remove this and leave it at the end of the file, where
2588 * Emacs will automagically detect them.
2589 * ---------------------------------------------------------------------
2592 * indent-tabs-mode: t
2596 * vim:noexpandtab:sw=4:ts=4: