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"
52 #include "vm/jit/jitcache.h"
54 #include "vmcore/class.h"
55 #include "vmcore/classcache.h"
56 #include "vmcore/linker.h"
57 #include "vmcore/loader.h"
58 #include "vmcore/options.h"
60 #if defined(ENABLE_STATISTICS)
61 # include "vmcore/statistics.h"
64 #include "vmcore/suck.h"
65 #include "vmcore/utf8.h"
68 #if defined(ENABLE_JAVASE)
69 /* We need to define some reflection functions here since we cannot
70 include native/vm/reflect.h as it includes generated header
73 java_object_t *reflect_constructor_new(methodinfo *m);
74 java_object_t *reflect_field_new(fieldinfo *f);
75 java_object_t *reflect_method_new(methodinfo *m);
79 /* global variables ***********************************************************/
81 /* frequently used classes ****************************************************/
83 /* Important system classes. */
85 classinfo *class_java_lang_Object;
86 classinfo *class_java_lang_Class;
87 classinfo *class_java_lang_ClassLoader;
88 classinfo *class_java_lang_Cloneable;
89 classinfo *class_java_lang_SecurityManager;
90 classinfo *class_java_lang_String;
91 classinfo *class_java_lang_System;
92 classinfo *class_java_lang_Thread;
93 classinfo *class_java_lang_ThreadGroup;
94 classinfo *class_java_lang_Throwable;
95 classinfo *class_java_io_Serializable;
97 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
98 classinfo *class_java_lang_VMSystem;
99 classinfo *class_java_lang_VMThread;
100 classinfo *class_java_lang_VMThrowable;
103 /* Important system exceptions. */
105 classinfo *class_java_lang_Exception;
106 classinfo *class_java_lang_ClassNotFoundException;
107 classinfo *class_java_lang_RuntimeException;
109 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
110 classinfo *class_sun_reflect_MagicAccessorImpl;
113 #if defined(ENABLE_JAVASE)
114 classinfo *class_java_lang_Void;
116 classinfo *class_java_lang_Boolean;
117 classinfo *class_java_lang_Byte;
118 classinfo *class_java_lang_Character;
119 classinfo *class_java_lang_Short;
120 classinfo *class_java_lang_Integer;
121 classinfo *class_java_lang_Long;
122 classinfo *class_java_lang_Float;
123 classinfo *class_java_lang_Double;
125 /* some classes which may be used more often */
127 #if defined(ENABLE_JAVASE)
128 classinfo *class_java_lang_StackTraceElement;
129 classinfo *class_java_lang_reflect_Constructor;
130 classinfo *class_java_lang_reflect_Field;
131 classinfo *class_java_lang_reflect_Method;
132 classinfo *class_java_security_PrivilegedAction;
133 classinfo *class_java_util_Vector;
134 classinfo *class_java_util_HashMap;
136 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
137 classinfo *class_java_lang_reflect_VMConstructor;
138 classinfo *class_java_lang_reflect_VMField;
139 classinfo *class_java_lang_reflect_VMMethod;
142 classinfo *arrayclass_java_lang_Object;
144 # if defined(ENABLE_ANNOTATIONS)
145 classinfo *class_sun_reflect_ConstantPool;
146 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
147 classinfo *class_sun_reflect_annotation_AnnotationParser;
152 /* pseudo classes for the typechecker */
154 classinfo *pseudo_class_Arraystub;
155 classinfo *pseudo_class_Null;
156 classinfo *pseudo_class_New;
159 /* class_set_packagename *******************************************************
161 Derive the package name from the class name and store it in the
164 An internal package name consists of the package name plus the
165 trailing '/', e.g. "java/lang/".
167 For classes in the unnamed package, the package name is set to
170 *******************************************************************************/
172 void class_set_packagename(classinfo *c)
177 p = UTF_END(c->name) - 1;
178 start = c->name->text;
180 if (c->name->text[0] == '[') {
181 /* Set packagename of arrays to the element's package. */
183 for (; *start == '['; start++);
185 /* Skip the 'L' in arrays of references. */
191 /* Search for last '/'. */
193 for (; (p > start) && (*p != '/'); --p);
195 /* If we found a '/' we set the package name plus the trailing
196 '/'. Otherwise we set the packagename to NULL. */
199 c->packagename = utf_new(start, p - start + 1);
201 c->packagename = NULL;
205 /* class_create_classinfo ******************************************************
207 Create a new classinfo struct. The class name is set to the given utf *,
208 most other fields are initialized to zero.
210 Note: classname may be NULL. In this case a not-yet-named classinfo is
211 created. The name must be filled in later and class_set_packagename
212 must be called after that.
214 *******************************************************************************/
216 classinfo *class_create_classinfo(utf *classname)
220 #if defined(ENABLE_STATISTICS)
222 size_classinfo += sizeof(classinfo);
225 /* we use a safe name for temporarily unnamed classes */
227 if (classname == NULL)
228 classname = utf_not_named_yet;
232 log_message_utf("Creating class: ", classname);
235 #if !defined(ENABLE_GC_BOEHM)
236 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
237 /*c = NEW(classinfo);
238 MZERO(c, classinfo, 1);*/
240 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
241 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
246 /* Set the header.vftbl of all loaded classes to the one of
247 java.lang.Class, so Java code can use a class as object. */
249 if (class_java_lang_Class != NULL)
250 if (class_java_lang_Class->vftbl != NULL)
251 c->object.header.vftbl = class_java_lang_Class->vftbl;
253 #if defined(ENABLE_JAVASE)
254 /* check if the class is a reference class and flag it */
256 if (classname == utf_java_lang_ref_SoftReference) {
257 c->flags |= ACC_CLASS_REFERENCE_SOFT;
259 else if (classname == utf_java_lang_ref_WeakReference) {
260 c->flags |= ACC_CLASS_REFERENCE_WEAK;
262 else if (classname == utf_java_lang_ref_PhantomReference) {
263 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
267 if (classname != utf_not_named_yet)
268 class_set_packagename(c);
269 #if defined (ENABLE_JITCACHE)
270 c->cache_file_fd = 0;
273 LOCK_INIT_OBJECT_LOCK(&c->object.header);
279 /* class_postset_header_vftbl **************************************************
281 Set the header.vftbl of all classes created before java.lang.Class
282 was linked. This is necessary that Java code can use a class as
285 *******************************************************************************/
287 void class_postset_header_vftbl(void)
291 classcache_name_entry *nmen;
292 classcache_class_entry *clsen;
294 assert(class_java_lang_Class);
296 for (slot = 0; slot < hashtable_classcache.size; slot++) {
297 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
299 for (; nmen; nmen = nmen->hashlink) {
300 /* iterate over all class entries */
302 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
305 /* now set the the vftbl */
307 if (c->object.header.vftbl == NULL)
308 c->object.header.vftbl = class_java_lang_Class->vftbl;
314 /* class_define ****************************************************************
316 Calls the loader and defines a class in the VM.
318 *******************************************************************************/
320 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
327 /* check if this class has already been defined */
329 c = classcache_lookup_defined_or_initiated(cl, name);
332 exceptions_throw_linkageerror("duplicate class definition: ", c);
337 /* create a new classinfo struct */
339 c = class_create_classinfo(name);
341 #if defined(ENABLE_STATISTICS)
344 if (opt_getloadingtime)
348 /* build a classbuffer with the given data */
350 cb = NEW(classbuffer);
357 /* preset the defining classloader */
361 /* load the class from this buffer */
363 r = load_class_from_classbuffer(cb);
367 FREE(cb, classbuffer);
369 #if defined(ENABLE_STATISTICS)
372 if (opt_getloadingtime)
377 /* If return value is NULL, we had a problem and the class is
378 not loaded. Now free the allocated memory, otherwise we
379 could run into a DOS. */
386 #if defined(ENABLE_JAVASE)
387 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
388 /* Store the protection domain. */
390 c->protectiondomain = pd;
394 /* Store the newly defined class in the class cache. This call
395 also checks whether a class of the same name has already been
396 defined by the same defining loader, and if so, replaces the
397 newly created class by the one defined earlier. */
399 /* Important: The classinfo given to classcache_store must be
400 fully prepared because another thread may return
401 this pointer after the lookup at to top of this
402 function directly after the class cache lock has
405 c = classcache_store(cl, c, true);
411 /* class_load_attribute_sourcefile *********************************************
413 SourceFile_attribute {
414 u2 attribute_name_index;
419 *******************************************************************************/
421 static bool class_load_attribute_sourcefile(classbuffer *cb)
432 /* check buffer size */
434 if (!suck_check_classbuffer_size(cb, 4 + 2))
437 /* check attribute length */
439 attribute_length = suck_u4(cb);
441 if (attribute_length != 2) {
442 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
446 /* there can be no more than one SourceFile attribute */
448 if (c->sourcefile != NULL) {
449 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
455 sourcefile_index = suck_u2(cb);
456 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
458 if (sourcefile == NULL)
461 /* store sourcefile */
463 c->sourcefile = sourcefile;
469 /* class_load_attribute_enclosingmethod ****************************************
471 EnclosingMethod_attribute {
472 u2 attribute_name_index;
478 *******************************************************************************/
480 #if defined(ENABLE_JAVASE)
481 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
487 classref_or_classinfo cr;
488 constant_nameandtype *cn;
494 /* check buffer size */
496 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
499 /* check attribute length */
501 attribute_length = suck_u4(cb);
503 if (attribute_length != 4) {
504 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
508 /* there can be no more than one EnclosingMethod attribute */
510 if (c->enclosingmethod != NULL) {
511 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
515 /* get class index */
517 class_index = suck_u2(cb);
518 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
520 /* get method index */
522 method_index = suck_u2(cb);
523 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
525 /* store info in classinfo */
527 c->enclosingclass.any = cr.any;
528 c->enclosingmethod = cn;
532 #endif /* defined(ENABLE_JAVASE) */
535 /* class_load_attributes *******************************************************
537 Read attributes from ClassFile.
540 u2 attribute_name_index;
542 u1 info[attribute_length];
545 InnerClasses_attribute {
546 u2 attribute_name_index;
550 *******************************************************************************/
552 bool class_load_attributes(classbuffer *cb)
555 uint16_t attributes_count;
556 uint16_t attribute_name_index;
558 innerclassinfo *info;
559 classref_or_classinfo inner;
560 classref_or_classinfo outer;
567 /* get attributes count */
569 if (!suck_check_classbuffer_size(cb, 2))
572 attributes_count = suck_u2(cb);
574 for (i = 0; i < attributes_count; i++) {
575 /* get attribute name */
577 if (!suck_check_classbuffer_size(cb, 2))
580 attribute_name_index = suck_u2(cb);
582 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
584 if (attribute_name == NULL)
587 if (attribute_name == utf_InnerClasses) {
590 if (c->innerclass != NULL) {
591 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
595 if (!suck_check_classbuffer_size(cb, 4 + 2))
598 /* skip attribute length */
601 /* number of records */
602 c->innerclasscount = suck_u2(cb);
604 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
607 /* allocate memory for innerclass structure */
608 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
610 for (j = 0; j < c->innerclasscount; j++) {
611 /* The innerclass structure contains a class with an encoded
612 name, its defining scope, its simple name and a bitmask of
615 info = c->innerclass + j;
617 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
618 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
619 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
622 /* If the current inner-class is the currently loaded
623 class check for some special flags. */
625 if (inner.ref->name == c->name) {
626 /* If an inner-class is not a member, its
627 outer-class is NULL. */
629 if (outer.ref != NULL) {
630 c->flags |= ACC_CLASS_MEMBER;
632 /* A member class doesn't have an
633 EnclosingMethod attribute, so set the
634 enclosing-class to be the same as the
637 c->declaringclass = outer;
638 c->enclosingclass = outer;
641 /* If an inner-class is anonymous, its name is
645 c->flags |= ACC_CLASS_ANONYMOUS;
648 info->inner_class = inner;
649 info->outer_class = outer;
654 else if (attribute_name == utf_SourceFile) {
657 if (!class_load_attribute_sourcefile(cb))
660 #if defined(ENABLE_JAVASE)
661 else if (attribute_name == utf_EnclosingMethod) {
662 /* EnclosingMethod */
664 if (!class_load_attribute_enclosingmethod(cb))
667 else if (attribute_name == utf_Signature) {
670 if (!loader_load_attribute_signature(cb, &(c->signature)))
675 #if defined(ENABLE_ANNOTATIONS)
676 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
677 /* RuntimeVisibleAnnotations */
678 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
681 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
682 /* RuntimeInvisibleAnnotations */
683 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
689 /* unknown attribute */
691 if (!loader_skip_attribute_body(cb))
700 /* class_freepool **************************************************************
702 Frees all resources used by this classes Constant Pool.
704 *******************************************************************************/
706 static void class_freecpool(classinfo *c)
712 if (c->cptags && c->cpinfos) {
713 for (idx = 0; idx < c->cpcount; idx++) {
714 tag = c->cptags[idx];
715 info = c->cpinfos[idx];
719 case CONSTANT_Fieldref:
720 case CONSTANT_Methodref:
721 case CONSTANT_InterfaceMethodref:
722 FREE(info, constant_FMIref);
724 case CONSTANT_Integer:
725 FREE(info, constant_integer);
728 FREE(info, constant_float);
731 FREE(info, constant_long);
733 case CONSTANT_Double:
734 FREE(info, constant_double);
736 case CONSTANT_NameAndType:
737 FREE(info, constant_nameandtype);
745 MFREE(c->cptags, u1, c->cpcount);
748 MFREE(c->cpinfos, voidptr, c->cpcount);
752 /* class_getconstant ***********************************************************
754 Retrieves the value at position 'pos' of the constantpool of a
755 class. If the type of the value is other than 'ctype', an error is
758 *******************************************************************************/
760 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
762 /* check index and type of constantpool entry */
763 /* (pos == 0 is caught by type comparison) */
765 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
766 exceptions_throw_classformaterror(c, "Illegal constant pool index");
770 return c->cpinfos[pos];
774 /* innerclass_getconstant ******************************************************
776 Like class_getconstant, but if cptags is ZERO, null is returned.
778 *******************************************************************************/
780 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
782 /* invalid position in constantpool */
784 if (pos >= c->cpcount) {
785 exceptions_throw_classformaterror(c, "Illegal constant pool index");
789 /* constantpool entry of type 0 */
791 if (c->cptags[pos] == 0)
794 /* check type of constantpool entry */
796 if (c->cptags[pos] != ctype) {
797 exceptions_throw_classformaterror(c, "Illegal constant pool index");
801 return c->cpinfos[pos];
805 /* class_free ******************************************************************
807 Frees all resources used by the class.
809 *******************************************************************************/
811 void class_free(classinfo *c)
816 #if defined(ENABLE_JITCACHE)
817 /* TODO: Find a way around the linker problem */
818 /* jitcache_freeclass(c);*/
823 if (c->interfaces != NULL)
824 MFREE(c->interfaces, classinfo*, c->interfacescount);
827 for (i = 0; i < c->fieldscount; i++)
828 field_free(&(c->fields[i]));
829 MFREE(c->fields, fieldinfo, c->fieldscount);
833 for (i = 0; i < c->methodscount; i++)
834 method_free(&(c->methods[i]));
835 MFREE(c->methods, methodinfo, c->methodscount);
838 if ((v = c->vftbl) != NULL) {
840 mem_free(v->arraydesc,sizeof(arraydescriptor));
842 for (i = 0; i < v->interfacetablelength; i++) {
843 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
845 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
847 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
848 sizeof(methodptr*) * (v->interfacetablelength -
849 (v->interfacetablelength > 0));
850 v = (vftbl_t*) (((methodptr*) v) -
851 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
856 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
858 /* if (c->classvftbl)
859 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
865 /* get_array_class *************************************************************
867 Returns the array class with the given name for the given
868 classloader, or NULL if an exception occurred.
870 Note: This function does eager loading.
872 *******************************************************************************/
874 static classinfo *get_array_class(utf *name,classloader_t *initloader,
875 classloader_t *defloader,bool link)
879 /* lookup this class in the classcache */
880 c = classcache_lookup(initloader,name);
882 c = classcache_lookup_defined(defloader,name);
885 /* we have to create it */
886 c = class_create_classinfo(name);
887 c = load_newly_created_array(c,initloader);
893 assert(c->state & CLASS_LOADED);
894 assert(c->classloader == defloader);
896 if (link && !(c->state & CLASS_LINKED))
900 assert(!link || (c->state & CLASS_LINKED));
906 /* class_array_of **************************************************************
908 Returns an array class with the given component class. The array
909 class is dynamically created if neccessary.
911 *******************************************************************************/
913 classinfo *class_array_of(classinfo *component, bool link)
922 cl = component->classloader;
926 /* Assemble the array class name */
927 namelen = component->name->blength;
929 if (component->name->text[0] == '[') {
930 /* the component is itself an array */
931 namebuf = DMNEW(char, namelen + 1);
933 MCOPY(namebuf + 1, component->name->text, char, namelen);
937 /* the component is a non-array class */
938 namebuf = DMNEW(char, namelen + 3);
941 MCOPY(namebuf + 2, component->name->text, char, namelen);
942 namebuf[2 + namelen] = ';';
946 u = utf_new(namebuf, namelen);
948 c = get_array_class(u, cl, cl, link);
956 /* class_multiarray_of *********************************************************
958 Returns an array class with the given dimension and element class.
959 The array class is dynamically created if neccessary.
961 *******************************************************************************/
963 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
973 log_text("Invalid array dimension requested");
977 /* Assemble the array class name */
978 namelen = element->name->blength;
980 if (element->name->text[0] == '[') {
981 /* the element is itself an array */
982 namebuf = DMNEW(char, namelen + dim);
983 memcpy(namebuf + dim, element->name->text, namelen);
987 /* the element is a non-array class */
988 namebuf = DMNEW(char, namelen + 2 + dim);
990 memcpy(namebuf + dim + 1, element->name->text, namelen);
991 namelen += (2 + dim);
992 namebuf[namelen - 1] = ';';
994 memset(namebuf, '[', dim);
996 c = get_array_class(utf_new(namebuf, namelen),
997 element->classloader,
998 element->classloader,
1007 /* class_lookup_classref *******************************************************
1009 Looks up the constant_classref for a given classname in the classref
1013 cls..............the class containing the reference
1014 name.............the name of the class refered to
1017 a pointer to a constant_classref, or
1018 NULL if the reference was not found
1020 *******************************************************************************/
1022 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
1024 constant_classref *ref;
1025 extra_classref *xref;
1030 assert(!cls->classrefcount || cls->classrefs);
1032 /* first search the main classref table */
1033 count = cls->classrefcount;
1034 ref = cls->classrefs;
1035 for (; count; --count, ++ref)
1036 if (ref->name == name)
1039 /* next try the list of extra classrefs */
1040 for (xref = cls->extclassrefs; xref; xref = xref->next) {
1041 if (xref->classref.name == name)
1042 return &(xref->classref);
1050 /* class_get_classref **********************************************************
1052 Returns the constant_classref for a given classname.
1055 cls..............the class containing the reference
1056 name.............the name of the class refered to
1059 a pointer to a constant_classref (never NULL)
1062 The given name is not checked for validity!
1064 *******************************************************************************/
1066 constant_classref *class_get_classref(classinfo *cls, utf *name)
1068 constant_classref *ref;
1069 extra_classref *xref;
1074 ref = class_lookup_classref(cls,name);
1078 xref = NEW(extra_classref);
1079 CLASSREF_INIT(xref->classref,cls,name);
1081 xref->next = cls->extclassrefs;
1082 cls->extclassrefs = xref;
1084 return &(xref->classref);
1088 /* class_get_self_classref *****************************************************
1090 Returns the constant_classref to the class itself.
1093 cls..............the class containing the reference
1096 a pointer to a constant_classref (never NULL)
1098 *******************************************************************************/
1100 constant_classref *class_get_self_classref(classinfo *cls)
1102 /* XXX this should be done in a faster way. Maybe always make */
1103 /* the classref of index 0 a self reference. */
1104 return class_get_classref(cls,cls->name);
1107 /* class_get_classref_multiarray_of ********************************************
1109 Returns an array type reference with the given dimension and element class
1113 dim..............the requested dimension
1114 dim must be in [1;255]. This is NOT checked!
1115 ref..............the component class reference
1118 a pointer to the class reference for the array type
1121 The referer of `ref` is used as the referer for the new classref.
1123 *******************************************************************************/
1125 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1129 constant_classref *cr;
1133 assert(dim >= 1 && dim <= 255);
1137 /* Assemble the array class name */
1138 namelen = ref->name->blength;
1140 if (ref->name->text[0] == '[') {
1141 /* the element is itself an array */
1142 namebuf = DMNEW(char, namelen + dim);
1143 memcpy(namebuf + dim, ref->name->text, namelen);
1147 /* the element is a non-array class */
1148 namebuf = DMNEW(char, namelen + 2 + dim);
1150 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1151 namelen += (2 + dim);
1152 namebuf[namelen - 1] = ';';
1154 memset(namebuf, '[', dim);
1156 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1164 /* class_get_classref_component_of *********************************************
1166 Returns the component classref of a given array type reference
1169 ref..............the array type reference
1172 a reference to the component class, or
1173 NULL if `ref` is not an object array type reference
1176 The referer of `ref` is used as the referer for the new classref.
1178 *******************************************************************************/
1180 constant_classref *class_get_classref_component_of(constant_classref *ref)
1187 name = ref->name->text;
1191 namelen = ref->name->blength - 1;
1196 else if (*name != '[') {
1200 return class_get_classref(ref->referer, utf_new(name, namelen));
1204 /* class_findmethod ************************************************************
1206 Searches a 'classinfo' structure for a method having the given name
1207 and descriptor. If descriptor is NULL, it is ignored.
1209 *******************************************************************************/
1211 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1216 for (i = 0; i < c->methodscount; i++) {
1217 m = &(c->methods[i]);
1219 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1227 /* class_resolvemethod *********************************************************
1229 Searches a class and it's super classes for a method.
1231 Superinterfaces are *not* searched.
1233 *******************************************************************************/
1235 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1240 m = class_findmethod(c, name, desc);
1245 /* JVM Specification bug:
1247 It is important NOT to resolve special <init> and <clinit>
1248 methods to super classes or interfaces; yet, this is not
1249 explicited in the specification. Section 5.4.3.3 should be
1250 updated appropriately. */
1252 if (name == utf_init || name == utf_clinit)
1262 /* class_resolveinterfacemethod_intern *****************************************
1264 Internally used helper function. Do not use this directly.
1266 *******************************************************************************/
1268 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1269 utf *name, utf *desc)
1274 /* try to find the method in the class */
1276 m = class_findmethod(c, name, desc);
1281 /* No method found? Try the super interfaces. */
1283 for (i = 0; i < c->interfacescount; i++) {
1284 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1290 /* no method found */
1296 /* class_resolveclassmethod ****************************************************
1298 Resolves a reference from REFERER to a method with NAME and DESC in
1301 If the method cannot be resolved the return value is NULL. If
1302 EXCEPT is true *exceptionptr is set, too.
1304 *******************************************************************************/
1306 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1307 classinfo *referer, bool throwexception)
1313 /* if (c->flags & ACC_INTERFACE) { */
1314 /* if (throwexception) */
1315 /* *exceptionptr = */
1316 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1320 /* try class c and its superclasses */
1324 m = class_resolvemethod(cls, name, desc);
1329 /* Try the super interfaces. */
1331 for (i = 0; i < c->interfacescount; i++) {
1332 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1339 exceptions_throw_nosuchmethoderror(c, name, desc);
1344 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1346 exceptions_throw_abstractmethoderror();
1351 /* XXX check access rights */
1357 /* class_resolveinterfacemethod ************************************************
1359 Resolves a reference from REFERER to a method with NAME and DESC in
1362 If the method cannot be resolved the return value is NULL. If
1363 EXCEPT is true *exceptionptr is set, too.
1365 *******************************************************************************/
1367 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1368 classinfo *referer, bool throwexception)
1372 if (!(c->flags & ACC_INTERFACE)) {
1374 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1379 mi = class_resolveinterfacemethod_intern(c, name, desc);
1384 /* try class java.lang.Object */
1386 mi = class_findmethod(class_java_lang_Object, name, desc);
1392 exceptions_throw_nosuchmethoderror(c, name, desc);
1398 /* class_findfield *************************************************************
1400 Searches for field with specified name and type in a classinfo
1401 structure. If no such field is found NULL is returned.
1403 *******************************************************************************/
1405 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1409 for (i = 0; i < c->fieldscount; i++)
1410 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1411 return &(c->fields[i]);
1413 if (c->super != NULL)
1414 return class_findfield(c->super, name, desc);
1420 /* class_findfield_approx ******************************************************
1422 Searches in 'classinfo'-structure for a field with the specified
1425 *******************************************************************************/
1427 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1431 /* get field index */
1433 i = class_findfield_index_by_name(c, name);
1435 /* field was not found, return */
1440 /* return field address */
1442 return &(c->fields[i]);
1446 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1450 for (i = 0; i < c->fieldscount; i++) {
1451 /* compare field names */
1453 if ((c->fields[i].name == name))
1457 /* field was not found, raise exception */
1459 exceptions_throw_nosuchfielderror(c, name);
1465 /****************** Function: class_resolvefield_int ***************************
1467 This is an internally used helper function. Do not use this directly.
1469 Tries to resolve a field having the given name and type.
1470 If the field cannot be resolved, NULL is returned.
1472 *******************************************************************************/
1474 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1479 /* search for field in class c */
1481 for (i = 0; i < c->fieldscount; i++) {
1482 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1483 return &(c->fields[i]);
1487 /* Try super interfaces recursively. */
1489 for (i = 0; i < c->interfacescount; i++) {
1490 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1496 /* Try super class. */
1498 if (c->super != NULL)
1499 return class_resolvefield_int(c->super, name, desc);
1507 /********************* Function: class_resolvefield ***************************
1509 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1511 If the field cannot be resolved the return value is NULL. If EXCEPT is
1512 true *exceptionptr is set, too.
1514 *******************************************************************************/
1516 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1517 classinfo *referer, bool throwexception)
1521 fi = class_resolvefield_int(c, name, desc);
1525 exceptions_throw_nosuchfielderror(c, name);
1530 /* XXX check access rights */
1536 /* class_issubclass ************************************************************
1538 Checks if sub is a descendant of super.
1540 *******************************************************************************/
1542 bool class_issubclass(classinfo *sub, classinfo *super)
1549 /* We reached java/lang/Object and did not find the requested
1555 /* We found the requested super class. */
1565 /* class_isanysubclass *********************************************************
1567 Checks a subclass relation between two classes. Implemented
1568 interfaces are interpreted as super classes.
1570 Return value: 1 ... sub is subclass of super
1573 *******************************************************************************/
1575 bool class_isanysubclass(classinfo *sub, classinfo *super)
1580 /* This is the trivial case. */
1585 /* Primitive classes are only subclasses of themselves. */
1587 if (class_is_primitive(sub) || class_is_primitive(super))
1590 /* Check for interfaces. */
1592 if (super->flags & ACC_INTERFACE) {
1593 result = (sub->vftbl->interfacetablelength > super->index) &&
1594 (sub->vftbl->interfacetable[-super->index] != NULL);
1597 /* java.lang.Object is the only super class of any
1600 if (sub->flags & ACC_INTERFACE)
1601 return (super == class_java_lang_Object);
1603 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1605 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1606 result = diffval <= (uint32_t) super->vftbl->diffval;
1608 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1615 /* class_is_assignable_from ****************************************************
1617 Return whether an instance of the "from" class parameter would be
1618 an instance of this class "to" as well.
1625 true .... is assignable
1626 false ... is not assignable
1628 *******************************************************************************/
1630 bool class_is_assignable_from(classinfo *to, classinfo *from)
1632 if (!(to->state & CLASS_LINKED))
1633 if (!link_class(to))
1636 if (!(from->state & CLASS_LINKED))
1637 if (!link_class(from))
1640 return class_isanysubclass(from, to);
1644 /* class_is_instance ***********************************************************
1646 Return if the given Java object is an instance of the given class.
1653 true .... is instance
1654 false ... is not instance
1656 *******************************************************************************/
1658 bool class_is_instance(classinfo *c, java_handle_t *h)
1660 if (!(c->state & CLASS_LINKED))
1664 return builtin_instanceof(h, c);
1668 /* class_get_componenttype *****************************************************
1670 Return the component class of the given class. If the given class
1671 is not an array, return NULL.
1673 *******************************************************************************/
1675 classinfo *class_get_componenttype(classinfo *c)
1677 classinfo *component;
1678 arraydescriptor *ad;
1680 /* XXX maybe we could find a way to do this without linking. */
1681 /* This way should be safe and easy, however. */
1683 if (!(c->state & CLASS_LINKED))
1687 ad = c->vftbl->arraydesc;
1692 if (ad->arraytype == ARRAYTYPE_OBJECT)
1693 component = ad->componentvftbl->clazz;
1695 component = primitive_class_get_by_type(ad->arraytype);
1701 /* class_get_declaredclasses ***************************************************
1703 Return an array of declared classes of the given class.
1705 *******************************************************************************/
1707 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1709 classref_or_classinfo inner;
1710 classref_or_classinfo outer;
1712 int declaredclasscount; /* number of declared classes */
1713 int pos; /* current declared class */
1714 java_handle_objectarray_t *oa; /* array of declared classes */
1718 declaredclasscount = 0;
1720 if (!class_is_primitive(c) && !class_is_array(c)) {
1721 /* Determine number of declared classes. */
1723 for (i = 0; i < c->innerclasscount; i++) {
1724 /* Get outer-class. If the inner-class is not a member
1725 class, the outer-class is NULL. */
1727 outer = c->innerclass[i].outer_class;
1729 if (outer.any == NULL)
1732 /* Check if outer-class is a classref or a real class and
1733 get the class name from the structure. */
1735 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1737 /* Outer class is this class. */
1739 if ((outername == c->name) &&
1740 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1741 declaredclasscount++;
1745 /* Allocate Class[] and check for OOM. */
1747 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1752 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1753 inner = c->innerclass[i].inner_class;
1754 outer = c->innerclass[i].outer_class;
1756 /* Get outer-class. If the inner-class is not a member class,
1757 the outer-class is NULL. */
1759 if (outer.any == NULL)
1762 /* Check if outer_class is a classref or a real class and get
1763 the class name from the structure. */
1765 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1767 /* Outer class is this class. */
1769 if ((outername == c->name) &&
1770 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1772 ic = resolve_classref_or_classinfo_eager(inner, false);
1777 if (!(ic->state & CLASS_LINKED))
1778 if (!link_class(ic))
1781 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1790 * Return an array of declared constructors of the given class.
1792 * @param c class to get the constructors of
1793 * @param publicOnly show only public fields
1795 * @return array of java.lang.reflect.Constructor
1797 #if defined(ENABLE_JAVASE)
1798 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1801 java_handle_objectarray_t* oa;
1807 /* Determine number of constructors. */
1811 for (i = 0; i < c->methodscount; i++) {
1812 m = &(c->methods[i]);
1814 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1815 (m->name == utf_init))
1819 /* Create array of constructors. */
1821 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1826 /* Get the constructors and store them in the array. */
1828 for (i = 0, index = 0; i < c->methodscount; i++) {
1829 m = &(c->methods[i]);
1831 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1832 (m->name == utf_init)) {
1833 /* Create Constructor object. This is actualy a
1834 java_lang_reflect_Constructor pointer, but we use a
1835 java_handle_t here, because we don't have the header
1836 available when building vmcore. */
1838 rc = reflect_constructor_new(m);
1840 /* Store object into array. */
1842 array_objectarray_element_set(oa, index, rc);
1852 /* class_get_declaredfields ****************************************************
1854 Return an array of declared fields of the given class.
1857 c ............ class to get the fields of
1858 publicOnly ... show only public fields
1861 array of java.lang.reflect.Field
1863 *******************************************************************************/
1865 #if defined(ENABLE_JAVASE)
1866 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1868 java_handle_objectarray_t *oa;
1875 /* Determine number of fields. */
1879 for (i = 0; i < c->fieldscount; i++)
1880 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1883 /* Create array of fields. */
1885 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1890 /* Get the fields and store them in the array. */
1892 for (i = 0, index = 0; i < c->fieldscount; i++) {
1893 f = &(c->fields[i]);
1895 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1896 /* Create Field object. This is actualy a
1897 java_lang_reflect_Field pointer, but we use a
1898 java_handle_t here, because we don't have the header
1899 available when building vmcore. */
1901 h = reflect_field_new(f);
1903 /* Store object into array. */
1905 array_objectarray_element_set(oa, index, h);
1915 /* class_get_declaredmethods ***************************************************
1917 Return an array of declared methods of the given class.
1920 c ............ class to get the methods of
1921 publicOnly ... show only public methods
1924 array of java.lang.reflect.Method
1926 *******************************************************************************/
1928 #if defined(ENABLE_JAVASE)
1929 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1931 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1932 methodinfo *m; /* the current method to be represented */
1938 /* JOWENN: array classes do not declare methods according to mauve
1939 test. It should be considered, if we should return to my old
1940 clone method overriding instead of declaring it as a member
1943 if (class_is_array(c))
1944 return builtin_anewarray(0, class_java_lang_reflect_Method);
1946 /* Determine number of methods. */
1950 for (i = 0; i < c->methodscount; i++) {
1951 m = &(c->methods[i]);
1953 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1954 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1955 !(m->flags & ACC_MIRANDA))
1959 /* Create array of methods. */
1961 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1966 /* Get the methods and store them in the array. */
1968 for (i = 0, index = 0; i < c->methodscount; i++) {
1969 m = &(c->methods[i]);
1971 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1972 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1973 !(m->flags & ACC_MIRANDA)) {
1974 /* Create method object. This is actualy a
1975 java_lang_reflect_Method pointer, but we use a
1976 java_handle_t here, because we don't have the header
1977 available when building vmcore. */
1979 h = reflect_method_new(m);
1981 /* Store object into array. */
1983 array_objectarray_element_set(oa, index, h);
1993 /* class_get_declaringclass ****************************************************
1995 If the class or interface given is a member of another class,
1996 return the declaring class. For array and primitive classes return
1999 *******************************************************************************/
2001 classinfo *class_get_declaringclass(classinfo *c)
2003 classref_or_classinfo cr;
2006 /* Get declaring class. */
2008 cr = c->declaringclass;
2013 /* Resolve the class if necessary. */
2015 if (IS_CLASSREF(cr)) {
2016 /* dc = resolve_classref_eager(cr.ref); */
2017 dc = resolve_classref_or_classinfo_eager(cr, true);
2022 /* Store the resolved class in the class structure. */
2033 /* class_get_enclosingclass ****************************************************
2035 Return the enclosing class for the given class.
2037 *******************************************************************************/
2039 classinfo *class_get_enclosingclass(classinfo *c)
2041 classref_or_classinfo cr;
2044 /* Get enclosing class. */
2046 cr = c->enclosingclass;
2051 /* Resolve the class if necessary. */
2053 if (IS_CLASSREF(cr)) {
2054 /* ec = resolve_classref_eager(cr.ref); */
2055 ec = resolve_classref_or_classinfo_eager(cr, true);
2060 /* Store the resolved class in the class structure. */
2072 * Return the enclosing constructor as java.lang.reflect.Constructor
2073 * object for the given class.
2075 * @param c class to return the enclosing constructor for
2077 * @return java.lang.reflect.Constructor object of the enclosing
2080 #if defined(ENABLE_JAVASE)
2081 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2086 m = class_get_enclosingmethod_raw(c);
2091 /* Check for <init>. */
2093 if (m->name != utf_init)
2096 /* Create Constructor object. */
2098 rc = reflect_constructor_new(m);
2105 /* class_get_enclosingmethod ***************************************************
2107 Return the enclosing method for the given class.
2110 c ... class to return the enclosing method for
2113 methodinfo of the enclosing method
2115 *******************************************************************************/
2117 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2119 constant_nameandtype *cn;
2123 /* get enclosing class and method */
2125 ec = class_get_enclosingclass(c);
2126 cn = c->enclosingmethod;
2128 /* check for enclosing class and method */
2136 /* find method in enclosing class */
2138 m = class_findmethod(ec, cn->name, cn->descriptor);
2141 exceptions_throw_internalerror("Enclosing method doesn't exist");
2150 * Return the enclosing method as java.lang.reflect.Method object for
2153 * @param c class to return the enclosing method for
2155 * @return java.lang.reflect.Method object of the enclosing method
2157 #if defined(ENABLE_JAVASE)
2158 java_handle_t* class_get_enclosingmethod(classinfo *c)
2163 m = class_get_enclosingmethod_raw(c);
2168 /* check for <init> */
2170 if (m->name == utf_init)
2173 /* create java.lang.reflect.Method object */
2175 rm = reflect_method_new(m);
2182 /* class_get_interfaces ********************************************************
2184 Return an array of interfaces of the given class.
2186 *******************************************************************************/
2188 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2191 java_handle_objectarray_t *oa;
2194 if (!(c->state & CLASS_LINKED))
2198 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2203 for (i = 0; i < c->interfacescount; i++) {
2204 ic = c->interfaces[i];
2206 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2213 /* class_get_annotations *******************************************************
2215 Get the unparsed declared annotations in a byte array
2219 c........the class of which the annotations should be returned
2222 The unparsed declared annotations in a byte array
2223 (or NULL if there aren't any).
2225 *******************************************************************************/
2227 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2229 #if defined(ENABLE_ANNOTATIONS)
2230 java_handle_t *annotations; /* unparsed annotations */
2232 LLNI_classinfo_field_get(c, annotations, annotations);
2234 return (java_handle_bytearray_t*)annotations;
2241 /* class_get_modifiers *********************************************************
2243 Get the modifier flags of the given class.
2246 c....the class of which the modifier flags should be returned
2247 ignoreInnerClassesAttrib
2251 *******************************************************************************/
2253 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2255 classref_or_classinfo inner;
2256 classref_or_classinfo outer;
2260 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2261 /* search for passed class as inner class */
2263 for (i = 0; i < c->innerclasscount; i++) {
2264 inner = c->innerclass[i].inner_class;
2265 outer = c->innerclass[i].outer_class;
2267 /* Check if inner is a classref or a real class and get
2268 the name of the structure */
2270 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2272 /* innerclass is this class */
2274 if (innername == c->name) {
2275 /* has the class actually an outer class? */
2278 /* return flags got from the outer class file */
2279 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2281 return c->flags & ACC_CLASS_REFLECT_MASK;
2286 /* passed class is no inner class or it was not requested */
2288 return c->flags & ACC_CLASS_REFLECT_MASK;
2292 /* class_get_signature *********************************************************
2294 Return the signature of the given class. For array and primitive
2295 classes return NULL.
2297 *******************************************************************************/
2299 #if defined(ENABLE_JAVASE)
2300 utf *class_get_signature(classinfo *c)
2302 /* For array and primitive classes return NULL. */
2304 if (class_is_array(c) || class_is_primitive(c))
2307 return c->signature;
2312 /* class_printflags ************************************************************
2314 Prints flags of a class.
2316 *******************************************************************************/
2318 #if !defined(NDEBUG)
2319 void class_printflags(classinfo *c)
2326 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2327 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2328 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2329 if (c->flags & ACC_STATIC) printf(" STATIC");
2330 if (c->flags & ACC_FINAL) printf(" FINAL");
2331 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2332 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2333 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2334 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2335 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2336 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2341 /* class_print *****************************************************************
2343 Prints classname plus flags.
2345 *******************************************************************************/
2347 #if !defined(NDEBUG)
2348 void class_print(classinfo *c)
2355 utf_display_printable_ascii(c->name);
2356 class_printflags(c);
2361 /* class_classref_print ********************************************************
2363 Prints classname plus referer class.
2365 *******************************************************************************/
2367 #if !defined(NDEBUG)
2368 void class_classref_print(constant_classref *cr)
2375 utf_display_printable_ascii(cr->name);
2378 class_print(cr->referer);
2386 /* class_println ***************************************************************
2388 Prints classname plus flags and new line.
2390 *******************************************************************************/
2392 #if !defined(NDEBUG)
2393 void class_println(classinfo *c)
2401 /* class_classref_println ******************************************************
2403 Prints classname plus referer class and new line.
2405 *******************************************************************************/
2407 #if !defined(NDEBUG)
2408 void class_classref_println(constant_classref *cr)
2410 class_classref_print(cr);
2416 /* class_classref_or_classinfo_print *******************************************
2418 Prints classname plus referer class.
2420 *******************************************************************************/
2422 #if !defined(NDEBUG)
2423 void class_classref_or_classinfo_print(classref_or_classinfo c)
2425 if (c.any == NULL) {
2426 printf("(classref_or_classinfo) NULL");
2430 class_classref_print(c.ref);
2437 /* class_classref_or_classinfo_println *****************************************
2439 Prints classname plus referer class and a newline.
2441 *******************************************************************************/
2443 #if !defined(NDEBUG)
2444 void class_classref_or_classinfo_println(classref_or_classinfo c)
2446 class_classref_or_classinfo_print(c);
2452 /* class_showconstantpool ******************************************************
2454 Dump the constant pool of the given class to stdout.
2456 *******************************************************************************/
2458 #if !defined(NDEBUG)
2459 void class_showconstantpool (classinfo *c)
2464 printf ("---- dump of constant pool ----\n");
2466 for (i=0; i<c->cpcount; i++) {
2467 printf ("#%d: ", (int) i);
2469 e = c -> cpinfos [i];
2472 switch (c -> cptags [i]) {
2473 case CONSTANT_Class:
2474 printf ("Classreference -> ");
2475 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2477 case CONSTANT_Fieldref:
2478 printf ("Fieldref -> ");
2479 field_fieldref_print((constant_FMIref *) e);
2481 case CONSTANT_Methodref:
2482 printf ("Methodref -> ");
2483 method_methodref_print((constant_FMIref *) e);
2485 case CONSTANT_InterfaceMethodref:
2486 printf ("InterfaceMethod -> ");
2487 method_methodref_print((constant_FMIref *) e);
2489 case CONSTANT_String:
2490 printf ("String -> ");
2491 utf_display_printable_ascii (e);
2493 case CONSTANT_Integer:
2494 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2496 case CONSTANT_Float:
2497 printf ("Float -> %f", ((constant_float*)e) -> value);
2499 case CONSTANT_Double:
2500 printf ("Double -> %f", ((constant_double*)e) -> value);
2504 u8 v = ((constant_long*)e) -> value;
2506 printf ("Long -> %ld", (long int) v);
2508 printf ("Long -> HI: %ld, LO: %ld\n",
2509 (long int) v.high, (long int) v.low);
2513 case CONSTANT_NameAndType:
2515 constant_nameandtype *cnt = e;
2516 printf ("NameAndType: ");
2517 utf_display_printable_ascii (cnt->name);
2519 utf_display_printable_ascii (cnt->descriptor);
2523 printf ("Utf8 -> ");
2524 utf_display_printable_ascii (e);
2527 log_text("Invalid type of ConstantPool-Entry");
2535 #endif /* !defined(NDEBUG) */
2538 /* class_showmethods ***********************************************************
2540 Dump info about the fields and methods of the given class to stdout.
2542 *******************************************************************************/
2544 #if !defined(NDEBUG)
2545 void class_showmethods (classinfo *c)
2549 printf("--------- Fields and Methods ----------------\n");
2551 class_printflags(c);
2555 utf_display_printable_ascii(c->name);
2560 utf_display_printable_ascii(c->super->name);
2564 printf("Index: %d\n", c->index);
2566 printf("Interfaces:\n");
2567 for (i = 0; i < c->interfacescount; i++) {
2569 utf_display_printable_ascii(c->interfaces[i]->name);
2570 printf (" (%d)\n", c->interfaces[i]->index);
2573 printf("Fields:\n");
2574 for (i = 0; i < c->fieldscount; i++)
2575 field_println(&(c->fields[i]));
2577 printf("Methods:\n");
2578 for (i = 0; i < c->methodscount; i++) {
2579 methodinfo *m = &(c->methods[i]);
2581 if (!(m->flags & ACC_STATIC))
2582 printf("vftblindex: %d ", m->vftblindex);
2587 printf ("Virtual function table:\n");
2588 for (i = 0; i < c->vftbl->vftbllength; i++)
2589 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2591 #endif /* !defined(NDEBUG) */
2595 * These are local overrides for various environment variables in Emacs.
2596 * Please do not remove this and leave it at the end of the file, where
2597 * Emacs will automagically detect them.
2598 * ---------------------------------------------------------------------
2601 * indent-tabs-mode: t
2605 * vim:noexpandtab:sw=4:ts=4: