1 /* src/vm/class.c - class related functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "mm/memory.h"
39 #include "native/llni.h"
41 #include "threads/lock-common.h"
42 #include "threads/mutex.hpp"
44 #include "toolbox/logging.h"
47 #include "vm/builtin.h"
49 #include "vm/classcache.h"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/linker.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
59 #if defined(ENABLE_STATISTICS)
60 # include "vm/statistics.h"
66 #include "vm/jit/asmpart.h"
69 /* class_set_packagename *******************************************************
71 Derive the package name from the class name and store it in the
74 An internal package name consists of the package name plus the
75 trailing '/', e.g. "java/lang/".
77 For classes in the unnamed package, the package name is set to
80 *******************************************************************************/
82 void class_set_packagename(classinfo *c)
87 p = UTF_END(c->name) - 1;
88 start = c->name->text;
90 if (c->name->text[0] == '[') {
91 /* Set packagename of arrays to the element's package. */
93 for (; *start == '['; start++);
95 /* Skip the 'L' in arrays of references. */
101 /* Search for last '/'. */
103 for (; (p > start) && (*p != '/'); --p);
105 /* If we found a '/' we set the package name plus the trailing
106 '/'. Otherwise we set the packagename to NULL. */
109 c->packagename = utf_new(start, p - start + 1);
111 c->packagename = NULL;
115 /* class_create_classinfo ******************************************************
117 Create a new classinfo struct. The class name is set to the given utf *,
118 most other fields are initialized to zero.
120 Note: classname may be NULL. In this case a not-yet-named classinfo is
121 created. The name must be filled in later and class_set_packagename
122 must be called after that.
124 *******************************************************************************/
126 classinfo *class_create_classinfo(utf *classname)
130 #if defined(ENABLE_STATISTICS)
132 size_classinfo += sizeof(classinfo);
135 /* we use a safe name for temporarily unnamed classes */
137 if (classname == NULL)
138 classname = utf_not_named_yet;
142 log_message_utf("Creating class: ", classname);
145 #if !defined(ENABLE_GC_BOEHM)
146 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
147 /*c = NEW(classinfo);
148 MZERO(c, classinfo, 1);*/
150 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
151 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
156 /* Set the header.vftbl of all loaded classes to the one of
157 java.lang.Class, so Java code can use a class as object. */
159 if (class_java_lang_Class != NULL)
160 if (class_java_lang_Class->vftbl != NULL)
161 c->object.header.vftbl = class_java_lang_Class->vftbl;
163 #if defined(ENABLE_JAVASE)
164 /* check if the class is a reference class and flag it */
166 if (classname == utf_java_lang_ref_SoftReference) {
167 c->flags |= ACC_CLASS_REFERENCE_SOFT;
169 else if (classname == utf_java_lang_ref_WeakReference) {
170 c->flags |= ACC_CLASS_REFERENCE_WEAK;
172 else if (classname == utf_java_lang_ref_PhantomReference) {
173 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
177 if (classname != utf_not_named_yet)
178 class_set_packagename(c);
180 LOCK_INIT_OBJECT_LOCK(&c->object.header);
186 /* class_postset_header_vftbl **************************************************
188 Set the header.vftbl of all classes created before java.lang.Class
189 was linked. This is necessary that Java code can use a class as
192 *******************************************************************************/
194 void class_postset_header_vftbl(void)
198 classcache_name_entry *nmen;
199 classcache_class_entry *clsen;
201 assert(class_java_lang_Class);
203 for (slot = 0; slot < hashtable_classcache.size; slot++) {
204 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
206 for (; nmen; nmen = nmen->hashlink) {
207 /* iterate over all class entries */
209 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
212 /* now set the the vftbl */
214 if (c->object.header.vftbl == NULL)
215 c->object.header.vftbl = class_java_lang_Class->vftbl;
221 /* class_define ****************************************************************
223 Calls the loader and defines a class in the VM.
225 *******************************************************************************/
227 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
234 /* check if this class has already been defined */
236 c = classcache_lookup_defined_or_initiated(cl, name);
239 exceptions_throw_linkageerror("duplicate class definition: ", c);
244 /* create a new classinfo struct */
246 c = class_create_classinfo(name);
248 #if defined(ENABLE_STATISTICS)
251 if (opt_getloadingtime)
255 /* build a classbuffer with the given data */
257 cb = NEW(classbuffer);
264 /* preset the defining classloader */
268 /* load the class from this buffer */
270 r = load_class_from_classbuffer(cb);
274 FREE(cb, classbuffer);
276 #if defined(ENABLE_STATISTICS)
279 if (opt_getloadingtime)
284 /* If return value is NULL, we had a problem and the class is
285 not loaded. Now free the allocated memory, otherwise we
286 could run into a DOS. */
293 #if defined(ENABLE_JAVASE)
294 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
295 /* Store the protection domain. */
297 c->protectiondomain = pd;
301 /* Store the newly defined class in the class cache. This call
302 also checks whether a class of the same name has already been
303 defined by the same defining loader, and if so, replaces the
304 newly created class by the one defined earlier. */
306 /* Important: The classinfo given to classcache_store must be
307 fully prepared because another thread may return
308 this pointer after the lookup at to top of this
309 function directly after the class cache lock has
312 c = classcache_store(cl, c, true);
318 /* class_load_attribute_sourcefile *********************************************
320 SourceFile_attribute {
321 u2 attribute_name_index;
326 *******************************************************************************/
328 static bool class_load_attribute_sourcefile(classbuffer *cb)
339 /* check buffer size */
341 if (!suck_check_classbuffer_size(cb, 4 + 2))
344 /* check attribute length */
346 attribute_length = suck_u4(cb);
348 if (attribute_length != 2) {
349 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
353 /* there can be no more than one SourceFile attribute */
355 if (c->sourcefile != NULL) {
356 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
362 sourcefile_index = suck_u2(cb);
363 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
365 if (sourcefile == NULL)
368 /* store sourcefile */
370 c->sourcefile = sourcefile;
376 /* class_load_attribute_enclosingmethod ****************************************
378 EnclosingMethod_attribute {
379 u2 attribute_name_index;
385 *******************************************************************************/
387 #if defined(ENABLE_JAVASE)
388 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
394 classref_or_classinfo cr;
395 constant_nameandtype *cn;
401 /* check buffer size */
403 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
406 /* check attribute length */
408 attribute_length = suck_u4(cb);
410 if (attribute_length != 4) {
411 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
415 /* there can be no more than one EnclosingMethod attribute */
417 if (c->enclosingmethod != NULL) {
418 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
422 /* get class index */
424 class_index = suck_u2(cb);
425 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
427 /* get method index */
429 method_index = suck_u2(cb);
430 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
432 /* store info in classinfo */
434 c->enclosingclass.any = cr.any;
435 c->enclosingmethod = cn;
439 #endif /* defined(ENABLE_JAVASE) */
442 /* class_load_attributes *******************************************************
444 Read attributes from ClassFile.
447 u2 attribute_name_index;
449 u1 info[attribute_length];
452 InnerClasses_attribute {
453 u2 attribute_name_index;
457 *******************************************************************************/
459 bool class_load_attributes(classbuffer *cb)
462 uint16_t attributes_count;
463 uint16_t attribute_name_index;
465 innerclassinfo *info;
466 classref_or_classinfo inner;
467 classref_or_classinfo outer;
474 /* get attributes count */
476 if (!suck_check_classbuffer_size(cb, 2))
479 attributes_count = suck_u2(cb);
481 for (i = 0; i < attributes_count; i++) {
482 /* get attribute name */
484 if (!suck_check_classbuffer_size(cb, 2))
487 attribute_name_index = suck_u2(cb);
489 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
491 if (attribute_name == NULL)
494 if (attribute_name == utf_InnerClasses) {
497 if (c->innerclass != NULL) {
498 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
502 if (!suck_check_classbuffer_size(cb, 4 + 2))
505 /* skip attribute length */
508 /* number of records */
509 c->innerclasscount = suck_u2(cb);
511 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
514 /* allocate memory for innerclass structure */
515 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
517 for (j = 0; j < c->innerclasscount; j++) {
518 /* The innerclass structure contains a class with an encoded
519 name, its defining scope, its simple name and a bitmask of
522 info = c->innerclass + j;
524 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
525 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
526 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
529 /* If the current inner-class is the currently loaded
530 class check for some special flags. */
532 if (inner.ref->name == c->name) {
533 /* If an inner-class is not a member, its
534 outer-class is NULL. */
536 if (outer.ref != NULL) {
537 c->flags |= ACC_CLASS_MEMBER;
539 /* A member class doesn't have an
540 EnclosingMethod attribute, so set the
541 enclosing-class to be the same as the
544 c->declaringclass = outer;
545 c->enclosingclass = outer;
548 /* If an inner-class is anonymous, its name is
552 c->flags |= ACC_CLASS_ANONYMOUS;
555 info->inner_class = inner;
556 info->outer_class = outer;
561 else if (attribute_name == utf_SourceFile) {
564 if (!class_load_attribute_sourcefile(cb))
567 #if defined(ENABLE_JAVASE)
568 else if (attribute_name == utf_EnclosingMethod) {
569 /* EnclosingMethod */
571 if (!class_load_attribute_enclosingmethod(cb))
574 else if (attribute_name == utf_Signature) {
577 if (!loader_load_attribute_signature(cb, &(c->signature)))
582 #if defined(ENABLE_ANNOTATIONS)
583 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
584 /* RuntimeVisibleAnnotations */
585 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
588 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
589 /* RuntimeInvisibleAnnotations */
590 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
596 /* unknown attribute */
598 if (!loader_skip_attribute_body(cb))
607 /* class_freepool **************************************************************
609 Frees all resources used by this classes Constant Pool.
611 *******************************************************************************/
613 static void class_freecpool(classinfo *c)
619 if (c->cptags && c->cpinfos) {
620 for (idx = 0; idx < c->cpcount; idx++) {
621 tag = c->cptags[idx];
622 info = c->cpinfos[idx];
626 case CONSTANT_Fieldref:
627 case CONSTANT_Methodref:
628 case CONSTANT_InterfaceMethodref:
629 FREE(info, constant_FMIref);
631 case CONSTANT_Integer:
632 FREE(info, constant_integer);
635 FREE(info, constant_float);
638 FREE(info, constant_long);
640 case CONSTANT_Double:
641 FREE(info, constant_double);
643 case CONSTANT_NameAndType:
644 FREE(info, constant_nameandtype);
652 MFREE(c->cptags, u1, c->cpcount);
655 MFREE(c->cpinfos, void*, c->cpcount);
659 /* class_getconstant ***********************************************************
661 Retrieves the value at position 'pos' of the constantpool of a
662 class. If the type of the value is other than 'ctype', an error is
665 *******************************************************************************/
667 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
669 /* check index and type of constantpool entry */
670 /* (pos == 0 is caught by type comparison) */
672 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
673 exceptions_throw_classformaterror(c, "Illegal constant pool index");
677 return c->cpinfos[pos];
681 /* innerclass_getconstant ******************************************************
683 Like class_getconstant, but if cptags is ZERO, null is returned.
685 *******************************************************************************/
687 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
689 /* invalid position in constantpool */
691 if (pos >= c->cpcount) {
692 exceptions_throw_classformaterror(c, "Illegal constant pool index");
696 /* constantpool entry of type 0 */
698 if (c->cptags[pos] == 0)
701 /* check type of constantpool entry */
703 if (c->cptags[pos] != ctype) {
704 exceptions_throw_classformaterror(c, "Illegal constant pool index");
708 return c->cpinfos[pos];
712 /* class_free ******************************************************************
714 Frees all resources used by the class.
716 *******************************************************************************/
718 void class_free(classinfo *c)
725 if (c->interfaces != NULL)
726 MFREE(c->interfaces, classinfo*, c->interfacescount);
729 for (i = 0; i < c->fieldscount; i++)
730 field_free(&(c->fields[i]));
731 MFREE(c->fields, fieldinfo, c->fieldscount);
735 for (i = 0; i < c->methodscount; i++)
736 method_free(&(c->methods[i]));
737 MFREE(c->methods, methodinfo, c->methodscount);
740 if ((v = c->vftbl) != NULL) {
742 mem_free(v->arraydesc,sizeof(arraydescriptor));
744 for (i = 0; i < v->interfacetablelength; i++) {
745 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
747 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
749 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
750 sizeof(methodptr*) * (v->interfacetablelength -
751 (v->interfacetablelength > 0));
752 v = (vftbl_t*) (((methodptr*) v) -
753 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
758 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
760 /* if (c->classvftbl)
761 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
767 /* get_array_class *************************************************************
769 Returns the array class with the given name for the given
770 classloader, or NULL if an exception occurred.
772 Note: This function does eager loading.
774 *******************************************************************************/
776 static classinfo *get_array_class(utf *name,classloader_t *initloader,
777 classloader_t *defloader,bool link)
781 /* lookup this class in the classcache */
782 c = classcache_lookup(initloader,name);
784 c = classcache_lookup_defined(defloader,name);
787 /* we have to create it */
788 c = class_create_classinfo(name);
789 c = load_newly_created_array(c,initloader);
795 assert(c->state & CLASS_LOADED);
796 assert(c->classloader == defloader);
798 if (link && !(c->state & CLASS_LINKED))
802 assert(!link || (c->state & CLASS_LINKED));
808 /* class_array_of **************************************************************
810 Returns an array class with the given component class. The array
811 class is dynamically created if neccessary.
813 *******************************************************************************/
815 classinfo *class_array_of(classinfo *component, bool link)
824 cl = component->classloader;
828 /* Assemble the array class name */
829 namelen = component->name->blength;
831 if (component->name->text[0] == '[') {
832 /* the component is itself an array */
833 namebuf = DMNEW(char, namelen + 1);
835 MCOPY(namebuf + 1, component->name->text, char, namelen);
839 /* the component is a non-array class */
840 namebuf = DMNEW(char, namelen + 3);
843 MCOPY(namebuf + 2, component->name->text, char, namelen);
844 namebuf[2 + namelen] = ';';
848 u = utf_new(namebuf, namelen);
850 c = get_array_class(u, cl, cl, link);
858 /* class_multiarray_of *********************************************************
860 Returns an array class with the given dimension and element class.
861 The array class is dynamically created if neccessary.
863 *******************************************************************************/
865 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
875 log_text("Invalid array dimension requested");
879 /* Assemble the array class name */
880 namelen = element->name->blength;
882 if (element->name->text[0] == '[') {
883 /* the element is itself an array */
884 namebuf = DMNEW(char, namelen + dim);
885 memcpy(namebuf + dim, element->name->text, namelen);
889 /* the element is a non-array class */
890 namebuf = DMNEW(char, namelen + 2 + dim);
892 memcpy(namebuf + dim + 1, element->name->text, namelen);
893 namelen += (2 + dim);
894 namebuf[namelen - 1] = ';';
896 memset(namebuf, '[', dim);
898 c = get_array_class(utf_new(namebuf, namelen),
899 element->classloader,
900 element->classloader,
909 /* class_lookup_classref *******************************************************
911 Looks up the constant_classref for a given classname in the classref
915 cls..............the class containing the reference
916 name.............the name of the class refered to
919 a pointer to a constant_classref, or
920 NULL if the reference was not found
922 *******************************************************************************/
924 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
926 constant_classref *ref;
927 extra_classref *xref;
932 assert(!cls->classrefcount || cls->classrefs);
934 /* first search the main classref table */
935 count = cls->classrefcount;
936 ref = cls->classrefs;
937 for (; count; --count, ++ref)
938 if (ref->name == name)
941 /* next try the list of extra classrefs */
942 for (xref = cls->extclassrefs; xref; xref = xref->next) {
943 if (xref->classref.name == name)
944 return &(xref->classref);
952 /* class_get_classref **********************************************************
954 Returns the constant_classref for a given classname.
957 cls..............the class containing the reference
958 name.............the name of the class refered to
961 a pointer to a constant_classref (never NULL)
964 The given name is not checked for validity!
966 *******************************************************************************/
968 constant_classref *class_get_classref(classinfo *cls, utf *name)
970 constant_classref *ref;
971 extra_classref *xref;
976 ref = class_lookup_classref(cls,name);
980 xref = NEW(extra_classref);
981 CLASSREF_INIT(xref->classref,cls,name);
983 xref->next = cls->extclassrefs;
984 cls->extclassrefs = xref;
986 return &(xref->classref);
990 /* class_get_self_classref *****************************************************
992 Returns the constant_classref to the class itself.
995 cls..............the class containing the reference
998 a pointer to a constant_classref (never NULL)
1000 *******************************************************************************/
1002 constant_classref *class_get_self_classref(classinfo *cls)
1004 /* XXX this should be done in a faster way. Maybe always make */
1005 /* the classref of index 0 a self reference. */
1006 return class_get_classref(cls,cls->name);
1009 /* class_get_classref_multiarray_of ********************************************
1011 Returns an array type reference with the given dimension and element class
1015 dim..............the requested dimension
1016 dim must be in [1;255]. This is NOT checked!
1017 ref..............the component class reference
1020 a pointer to the class reference for the array type
1023 The referer of `ref` is used as the referer for the new classref.
1025 *******************************************************************************/
1027 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1031 constant_classref *cr;
1035 assert(dim >= 1 && dim <= 255);
1039 /* Assemble the array class name */
1040 namelen = ref->name->blength;
1042 if (ref->name->text[0] == '[') {
1043 /* the element is itself an array */
1044 namebuf = DMNEW(char, namelen + dim);
1045 memcpy(namebuf + dim, ref->name->text, namelen);
1049 /* the element is a non-array class */
1050 namebuf = DMNEW(char, namelen + 2 + dim);
1052 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1053 namelen += (2 + dim);
1054 namebuf[namelen - 1] = ';';
1056 memset(namebuf, '[', dim);
1058 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1066 /* class_get_classref_component_of *********************************************
1068 Returns the component classref of a given array type reference
1071 ref..............the array type reference
1074 a reference to the component class, or
1075 NULL if `ref` is not an object array type reference
1078 The referer of `ref` is used as the referer for the new classref.
1080 *******************************************************************************/
1082 constant_classref *class_get_classref_component_of(constant_classref *ref)
1089 name = ref->name->text;
1093 namelen = ref->name->blength - 1;
1098 else if (*name != '[') {
1102 return class_get_classref(ref->referer, utf_new(name, namelen));
1106 /* class_findmethod ************************************************************
1108 Searches a 'classinfo' structure for a method having the given name
1109 and descriptor. If descriptor is NULL, it is ignored.
1111 *******************************************************************************/
1113 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1118 for (i = 0; i < c->methodscount; i++) {
1119 m = &(c->methods[i]);
1121 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1129 /* class_resolvemethod *********************************************************
1131 Searches a class and it's super classes for a method.
1133 Superinterfaces are *not* searched.
1135 *******************************************************************************/
1137 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1142 m = class_findmethod(c, name, desc);
1147 /* JVM Specification bug:
1149 It is important NOT to resolve special <init> and <clinit>
1150 methods to super classes or interfaces; yet, this is not
1151 explicited in the specification. Section 5.4.3.3 should be
1152 updated appropriately. */
1154 if (name == utf_init || name == utf_clinit)
1164 /* class_resolveinterfacemethod_intern *****************************************
1166 Internally used helper function. Do not use this directly.
1168 *******************************************************************************/
1170 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1171 utf *name, utf *desc)
1176 /* try to find the method in the class */
1178 m = class_findmethod(c, name, desc);
1183 /* No method found? Try the super interfaces. */
1185 for (i = 0; i < c->interfacescount; i++) {
1186 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1192 /* no method found */
1198 /* class_resolveclassmethod ****************************************************
1200 Resolves a reference from REFERER to a method with NAME and DESC in
1203 If the method cannot be resolved the return value is NULL. If
1204 EXCEPT is true *exceptionptr is set, too.
1206 *******************************************************************************/
1208 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1209 classinfo *referer, bool throwexception)
1215 /* if (c->flags & ACC_INTERFACE) { */
1216 /* if (throwexception) */
1217 /* *exceptionptr = */
1218 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1222 /* try class c and its superclasses */
1226 m = class_resolvemethod(cls, name, desc);
1231 /* Try the super interfaces. */
1233 for (i = 0; i < c->interfacescount; i++) {
1234 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1241 exceptions_throw_nosuchmethoderror(c, name, desc);
1246 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1248 exceptions_throw_abstractmethoderror();
1253 /* XXX check access rights */
1259 /* class_resolveinterfacemethod ************************************************
1261 Resolves a reference from REFERER to a method with NAME and DESC in
1264 If the method cannot be resolved the return value is NULL. If
1265 EXCEPT is true *exceptionptr is set, too.
1267 *******************************************************************************/
1269 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1270 classinfo *referer, bool throwexception)
1274 if (!(c->flags & ACC_INTERFACE)) {
1276 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1281 mi = class_resolveinterfacemethod_intern(c, name, desc);
1286 /* try class java.lang.Object */
1288 mi = class_findmethod(class_java_lang_Object, name, desc);
1294 exceptions_throw_nosuchmethoderror(c, name, desc);
1300 /* class_findfield *************************************************************
1302 Searches for field with specified name and type in a classinfo
1303 structure. If no such field is found NULL is returned.
1305 *******************************************************************************/
1307 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1311 for (i = 0; i < c->fieldscount; i++)
1312 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1313 return &(c->fields[i]);
1315 if (c->super != NULL)
1316 return class_findfield(c->super, name, desc);
1322 /* class_findfield_approx ******************************************************
1324 Searches in 'classinfo'-structure for a field with the specified
1327 *******************************************************************************/
1329 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1331 for (int32_t i = 0; i < c->fieldscount; i++) {
1332 fieldinfo* f = &(c->fields[i]);
1334 if (f->name == name)
1339 exceptions_throw_nosuchfielderror(c, name);
1344 /****************** Function: class_resolvefield_int ***************************
1346 This is an internally used helper function. Do not use this directly.
1348 Tries to resolve a field having the given name and type.
1349 If the field cannot be resolved, NULL is returned.
1351 *******************************************************************************/
1353 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1358 /* search for field in class c */
1360 for (i = 0; i < c->fieldscount; i++) {
1361 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1362 return &(c->fields[i]);
1366 /* Try super interfaces recursively. */
1368 for (i = 0; i < c->interfacescount; i++) {
1369 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1375 /* Try super class. */
1377 if (c->super != NULL)
1378 return class_resolvefield_int(c->super, name, desc);
1386 /********************* Function: class_resolvefield ***************************
1388 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1390 If the field cannot be resolved, an exception is thrown and the
1391 return value is NULL.
1393 *******************************************************************************/
1395 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1399 fi = class_resolvefield_int(c, name, desc);
1402 exceptions_throw_nosuchfielderror(c, name);
1406 /* XXX check access rights */
1412 /* class_issubclass ************************************************************
1414 Checks if sub is a descendant of super.
1416 *******************************************************************************/
1418 bool class_issubclass(classinfo *sub, classinfo *super)
1425 /* We reached java/lang/Object and did not find the requested
1431 /* We found the requested super class. */
1441 /* class_isanysubclass *********************************************************
1443 Checks a subclass relation between two classes. Implemented
1444 interfaces are interpreted as super classes.
1446 Return value: 1 ... sub is subclass of super
1449 *******************************************************************************/
1451 bool class_isanysubclass(classinfo *sub, classinfo *super)
1456 /* This is the trivial case. */
1461 /* Primitive classes are only subclasses of themselves. */
1463 if (class_is_primitive(sub) || class_is_primitive(super))
1466 /* Check for interfaces. */
1468 if (super->flags & ACC_INTERFACE) {
1469 result = (sub->vftbl->interfacetablelength > super->index) &&
1470 (sub->vftbl->interfacetable[-super->index] != NULL);
1473 /* java.lang.Object is the only super class of any
1476 if (sub->flags & ACC_INTERFACE)
1477 return (super == class_java_lang_Object);
1479 Mutex_lock(linker_classrenumber_mutex);
1481 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1482 result = diffval <= (uint32_t) super->vftbl->diffval;
1484 Mutex_unlock(linker_classrenumber_mutex);
1491 /* class_is_assignable_from ****************************************************
1493 Return whether an instance of the "from" class parameter would be
1494 an instance of this class "to" as well.
1501 true .... is assignable
1502 false ... is not assignable
1504 *******************************************************************************/
1506 bool class_is_assignable_from(classinfo *to, classinfo *from)
1508 if (!(to->state & CLASS_LINKED))
1509 if (!link_class(to))
1512 if (!(from->state & CLASS_LINKED))
1513 if (!link_class(from))
1516 return class_isanysubclass(from, to);
1520 /* class_is_instance ***********************************************************
1522 Return if the given Java object is an instance of the given class.
1529 true .... is instance
1530 false ... is not instance
1532 *******************************************************************************/
1534 bool class_is_instance(classinfo *c, java_handle_t *h)
1536 if (!(c->state & CLASS_LINKED))
1540 return builtin_instanceof(h, c);
1544 /* class_get_componenttype *****************************************************
1546 Return the component class of the given class. If the given class
1547 is not an array, return NULL.
1549 *******************************************************************************/
1551 classinfo *class_get_componenttype(classinfo *c)
1553 classinfo *component;
1554 arraydescriptor *ad;
1556 /* XXX maybe we could find a way to do this without linking. */
1557 /* This way should be safe and easy, however. */
1559 if (!(c->state & CLASS_LINKED))
1563 ad = c->vftbl->arraydesc;
1568 if (ad->arraytype == ARRAYTYPE_OBJECT)
1569 component = ad->componentvftbl->clazz;
1571 component = Primitive_get_class_by_type(ad->arraytype);
1577 /* class_get_declaredclasses ***************************************************
1579 Return an array of declared classes of the given class.
1581 *******************************************************************************/
1583 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1585 classref_or_classinfo inner;
1586 classref_or_classinfo outer;
1588 int declaredclasscount; /* number of declared classes */
1589 int pos; /* current declared class */
1590 java_handle_objectarray_t *oa; /* array of declared classes */
1594 declaredclasscount = 0;
1596 if (!class_is_primitive(c) && !class_is_array(c)) {
1597 /* Determine number of declared classes. */
1599 for (i = 0; i < c->innerclasscount; i++) {
1600 /* Get outer-class. If the inner-class is not a member
1601 class, the outer-class is NULL. */
1603 outer = c->innerclass[i].outer_class;
1605 if (outer.any == NULL)
1608 /* Check if outer-class is a classref or a real class and
1609 get the class name from the structure. */
1611 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1613 /* Outer class is this class. */
1615 if ((outername == c->name) &&
1616 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1617 declaredclasscount++;
1621 /* Allocate Class[] and check for OOM. */
1623 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1628 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1629 inner = c->innerclass[i].inner_class;
1630 outer = c->innerclass[i].outer_class;
1632 /* Get outer-class. If the inner-class is not a member class,
1633 the outer-class is NULL. */
1635 if (outer.any == NULL)
1638 /* Check if outer_class is a classref or a real class and get
1639 the class name from the structure. */
1641 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1643 /* Outer class is this class. */
1645 if ((outername == c->name) &&
1646 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1648 ic = resolve_classref_or_classinfo_eager(inner, false);
1653 if (!(ic->state & CLASS_LINKED))
1654 if (!link_class(ic))
1657 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1666 * Return an array of declared constructors of the given class.
1668 * @param c class to get the constructors of
1669 * @param publicOnly show only public fields
1671 * @return array of java.lang.reflect.Constructor
1673 #if defined(ENABLE_JAVASE)
1674 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1677 java_handle_objectarray_t* oa;
1683 /* Determine number of constructors. */
1687 for (i = 0; i < c->methodscount; i++) {
1688 m = &(c->methods[i]);
1690 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1691 (m->name == utf_init))
1695 /* Create array of constructors. */
1697 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1702 /* Get the constructors and store them in the array. */
1704 for (i = 0, index = 0; i < c->methodscount; i++) {
1705 m = &(c->methods[i]);
1707 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1708 (m->name == utf_init)) {
1709 // Create a java.lang.reflect.Constructor object.
1711 rc = java_lang_reflect_Constructor_create(m);
1713 /* Store object into array. */
1715 array_objectarray_element_set(oa, index, rc);
1725 /* class_get_declaredfields ****************************************************
1727 Return an array of declared fields of the given class.
1730 c ............ class to get the fields of
1731 publicOnly ... show only public fields
1734 array of java.lang.reflect.Field
1736 *******************************************************************************/
1738 #if defined(ENABLE_JAVASE)
1739 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1741 java_handle_objectarray_t *oa;
1748 /* Determine number of fields. */
1752 for (i = 0; i < c->fieldscount; i++)
1753 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1756 /* Create array of fields. */
1758 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1763 /* Get the fields and store them in the array. */
1765 for (i = 0, index = 0; i < c->fieldscount; i++) {
1766 f = &(c->fields[i]);
1768 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1769 // Create a java.lang.reflect.Field object.
1771 h = java_lang_reflect_Field_create(f);
1773 /* Store object into array. */
1775 array_objectarray_element_set(oa, index, h);
1785 /* class_get_declaredmethods ***************************************************
1787 Return an array of declared methods of the given class.
1790 c ............ class to get the methods of
1791 publicOnly ... show only public methods
1794 array of java.lang.reflect.Method
1796 *******************************************************************************/
1798 #if defined(ENABLE_JAVASE)
1799 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1801 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1802 methodinfo *m; /* the current method to be represented */
1808 /* JOWENN: array classes do not declare methods according to mauve
1809 test. It should be considered, if we should return to my old
1810 clone method overriding instead of declaring it as a member
1813 if (class_is_array(c))
1814 return builtin_anewarray(0, class_java_lang_reflect_Method);
1816 /* Determine number of methods. */
1820 for (i = 0; i < c->methodscount; i++) {
1821 m = &(c->methods[i]);
1823 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1824 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1825 !(m->flags & ACC_MIRANDA))
1829 /* Create array of methods. */
1831 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1836 /* Get the methods and store them in the array. */
1838 for (i = 0, index = 0; i < c->methodscount; i++) {
1839 m = &(c->methods[i]);
1841 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1842 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1843 !(m->flags & ACC_MIRANDA)) {
1844 // Create java.lang.reflect.Method object.
1846 h = java_lang_reflect_Method_create(m);
1848 /* Store object into array. */
1850 array_objectarray_element_set(oa, index, h);
1860 /* class_get_declaringclass ****************************************************
1862 If the class or interface given is a member of another class,
1863 return the declaring class. For array and primitive classes return
1866 *******************************************************************************/
1868 classinfo *class_get_declaringclass(classinfo *c)
1870 classref_or_classinfo cr;
1873 /* Get declaring class. */
1875 cr = c->declaringclass;
1880 /* Resolve the class if necessary. */
1882 if (IS_CLASSREF(cr)) {
1883 /* dc = resolve_classref_eager(cr.ref); */
1884 dc = resolve_classref_or_classinfo_eager(cr, true);
1889 /* Store the resolved class in the class structure. */
1900 /* class_get_enclosingclass ****************************************************
1902 Return the enclosing class for the given class.
1904 *******************************************************************************/
1906 classinfo *class_get_enclosingclass(classinfo *c)
1908 classref_or_classinfo cr;
1911 /* Get enclosing class. */
1913 cr = c->enclosingclass;
1918 /* Resolve the class if necessary. */
1920 if (IS_CLASSREF(cr)) {
1921 /* ec = resolve_classref_eager(cr.ref); */
1922 ec = resolve_classref_or_classinfo_eager(cr, true);
1927 /* Store the resolved class in the class structure. */
1939 * Return the enclosing constructor as java.lang.reflect.Constructor
1940 * object for the given class.
1942 * @param c class to return the enclosing constructor for
1944 * @return java.lang.reflect.Constructor object of the enclosing
1947 #if defined(ENABLE_JAVASE)
1948 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1953 m = class_get_enclosingmethod_raw(c);
1958 /* Check for <init>. */
1960 if (m->name != utf_init)
1963 // Create a java.lang.reflect.Constructor object.
1965 rc = java_lang_reflect_Constructor_create(m);
1972 /* class_get_enclosingmethod ***************************************************
1974 Return the enclosing method for the given class.
1977 c ... class to return the enclosing method for
1980 methodinfo of the enclosing method
1982 *******************************************************************************/
1984 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1986 constant_nameandtype *cn;
1990 /* get enclosing class and method */
1992 ec = class_get_enclosingclass(c);
1993 cn = c->enclosingmethod;
1995 /* check for enclosing class and method */
2003 /* find method in enclosing class */
2005 m = class_findmethod(ec, cn->name, cn->descriptor);
2008 exceptions_throw_internalerror("Enclosing method doesn't exist");
2017 * Return the enclosing method as java.lang.reflect.Method object for
2020 * @param c class to return the enclosing method for
2022 * @return java.lang.reflect.Method object of the enclosing method
2024 #if defined(ENABLE_JAVASE)
2025 java_handle_t* class_get_enclosingmethod(classinfo *c)
2030 m = class_get_enclosingmethod_raw(c);
2035 /* check for <init> */
2037 if (m->name == utf_init)
2040 // Create a java.lang.reflect.Method object.
2042 rm = java_lang_reflect_Method_create(m);
2049 /* class_get_interfaces ********************************************************
2051 Return an array of interfaces of the given class.
2053 *******************************************************************************/
2055 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2058 java_handle_objectarray_t *oa;
2061 if (!(c->state & CLASS_LINKED))
2065 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2070 for (i = 0; i < c->interfacescount; i++) {
2071 ic = c->interfaces[i];
2073 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2080 /* class_get_annotations *******************************************************
2082 Get the unparsed declared annotations in a byte array
2086 c........the class of which the annotations should be returned
2089 The unparsed declared annotations in a byte array
2090 (or NULL if there aren't any).
2092 *******************************************************************************/
2094 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2096 #if defined(ENABLE_ANNOTATIONS)
2097 java_handle_t *annotations; /* unparsed annotations */
2099 LLNI_classinfo_field_get(c, annotations, annotations);
2101 return (java_handle_bytearray_t*)annotations;
2108 /* class_get_modifiers *********************************************************
2110 Get the modifier flags of the given class.
2113 c....the class of which the modifier flags should be returned
2114 ignoreInnerClassesAttrib
2118 *******************************************************************************/
2120 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2122 classref_or_classinfo inner;
2123 classref_or_classinfo outer;
2127 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2128 /* search for passed class as inner class */
2130 for (i = 0; i < c->innerclasscount; i++) {
2131 inner = c->innerclass[i].inner_class;
2132 outer = c->innerclass[i].outer_class;
2134 /* Check if inner is a classref or a real class and get
2135 the name of the structure */
2137 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2139 /* innerclass is this class */
2141 if (innername == c->name) {
2142 /* has the class actually an outer class? */
2145 /* return flags got from the outer class file */
2146 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2148 return c->flags & ACC_CLASS_REFLECT_MASK;
2153 /* passed class is no inner class or it was not requested */
2155 return c->flags & ACC_CLASS_REFLECT_MASK;
2159 /* class_get_signature *********************************************************
2161 Return the signature of the given class. For array and primitive
2162 classes return NULL.
2164 *******************************************************************************/
2166 #if defined(ENABLE_JAVASE)
2167 utf *class_get_signature(classinfo *c)
2169 /* For array and primitive classes return NULL. */
2171 if (class_is_array(c) || class_is_primitive(c))
2174 return c->signature;
2179 /* class_printflags ************************************************************
2181 Prints flags of a class.
2183 *******************************************************************************/
2185 #if !defined(NDEBUG)
2186 void class_printflags(classinfo *c)
2193 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2194 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2195 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2196 if (c->flags & ACC_STATIC) printf(" STATIC");
2197 if (c->flags & ACC_FINAL) printf(" FINAL");
2198 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2199 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2200 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2201 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2202 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2203 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2208 /* class_print *****************************************************************
2210 Prints classname plus flags.
2212 *******************************************************************************/
2214 #if !defined(NDEBUG)
2215 void class_print(classinfo *c)
2222 utf_display_printable_ascii(c->name);
2223 class_printflags(c);
2228 /* class_classref_print ********************************************************
2230 Prints classname plus referer class.
2232 *******************************************************************************/
2234 #if !defined(NDEBUG)
2235 void class_classref_print(constant_classref *cr)
2242 utf_display_printable_ascii(cr->name);
2245 class_print(cr->referer);
2253 /* class_println ***************************************************************
2255 Prints classname plus flags and new line.
2257 *******************************************************************************/
2259 #if !defined(NDEBUG)
2260 void class_println(classinfo *c)
2268 /* class_classref_println ******************************************************
2270 Prints classname plus referer class and new line.
2272 *******************************************************************************/
2274 #if !defined(NDEBUG)
2275 void class_classref_println(constant_classref *cr)
2277 class_classref_print(cr);
2283 /* class_classref_or_classinfo_print *******************************************
2285 Prints classname plus referer class.
2287 *******************************************************************************/
2289 #if !defined(NDEBUG)
2290 void class_classref_or_classinfo_print(classref_or_classinfo c)
2292 if (c.any == NULL) {
2293 printf("(classref_or_classinfo) NULL");
2297 class_classref_print(c.ref);
2304 /* class_classref_or_classinfo_println *****************************************
2306 Prints classname plus referer class and a newline.
2308 *******************************************************************************/
2310 #if !defined(NDEBUG)
2311 void class_classref_or_classinfo_println(classref_or_classinfo c)
2313 class_classref_or_classinfo_print(c);
2319 /* class_showconstantpool ******************************************************
2321 Dump the constant pool of the given class to stdout.
2323 *******************************************************************************/
2325 #if !defined(NDEBUG)
2326 void class_showconstantpool (classinfo *c)
2331 printf ("---- dump of constant pool ----\n");
2333 for (i=0; i<c->cpcount; i++) {
2334 printf ("#%d: ", (int) i);
2336 e = c -> cpinfos [i];
2339 switch (c -> cptags [i]) {
2340 case CONSTANT_Class:
2341 printf ("Classreference -> ");
2342 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2344 case CONSTANT_Fieldref:
2345 printf ("Fieldref -> ");
2346 field_fieldref_print((constant_FMIref *) e);
2348 case CONSTANT_Methodref:
2349 printf ("Methodref -> ");
2350 method_methodref_print((constant_FMIref *) e);
2352 case CONSTANT_InterfaceMethodref:
2353 printf ("InterfaceMethod -> ");
2354 method_methodref_print((constant_FMIref *) e);
2356 case CONSTANT_String:
2357 printf ("String -> ");
2358 utf_display_printable_ascii (e);
2360 case CONSTANT_Integer:
2361 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2363 case CONSTANT_Float:
2364 printf ("Float -> %f", ((constant_float*)e) -> value);
2366 case CONSTANT_Double:
2367 printf ("Double -> %f", ((constant_double*)e) -> value);
2371 u8 v = ((constant_long*)e) -> value;
2373 printf ("Long -> %ld", (long int) v);
2375 printf ("Long -> HI: %ld, LO: %ld\n",
2376 (long int) v.high, (long int) v.low);
2380 case CONSTANT_NameAndType:
2382 constant_nameandtype *cnt = e;
2383 printf ("NameAndType: ");
2384 utf_display_printable_ascii (cnt->name);
2386 utf_display_printable_ascii (cnt->descriptor);
2390 printf ("Utf8 -> ");
2391 utf_display_printable_ascii (e);
2394 log_text("Invalid type of ConstantPool-Entry");
2402 #endif /* !defined(NDEBUG) */
2405 /* class_showmethods ***********************************************************
2407 Dump info about the fields and methods of the given class to stdout.
2409 *******************************************************************************/
2411 #if !defined(NDEBUG)
2412 void class_showmethods (classinfo *c)
2416 printf("--------- Fields and Methods ----------------\n");
2418 class_printflags(c);
2422 utf_display_printable_ascii(c->name);
2427 utf_display_printable_ascii(c->super->name);
2431 printf("Index: %d\n", c->index);
2433 printf("Interfaces:\n");
2434 for (i = 0; i < c->interfacescount; i++) {
2436 utf_display_printable_ascii(c->interfaces[i]->name);
2437 printf (" (%d)\n", c->interfaces[i]->index);
2440 printf("Fields:\n");
2441 for (i = 0; i < c->fieldscount; i++)
2442 field_println(&(c->fields[i]));
2444 printf("Methods:\n");
2445 for (i = 0; i < c->methodscount; i++) {
2446 methodinfo *m = &(c->methods[i]);
2448 if (!(m->flags & ACC_STATIC))
2449 printf("vftblindex: %d ", m->vftblindex);
2454 printf ("Virtual function table:\n");
2455 for (i = 0; i < c->vftbl->vftbllength; i++)
2456 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2458 #endif /* !defined(NDEBUG) */
2462 * These are local overrides for various environment variables in Emacs.
2463 * Please do not remove this and leave it at the end of the file, where
2464 * Emacs will automagically detect them.
2465 * ---------------------------------------------------------------------
2468 * indent-tabs-mode: t
2472 * vim:noexpandtab:sw=4:ts=4: