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"
43 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
48 #include "vm/classcache.h"
49 #include "vm/exceptions.hpp"
50 #include "vm/global.h"
51 #include "vm/globals.hpp"
52 #include "vm/javaobjects.hpp"
53 #include "vm/linker.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/resolve.h"
58 #if defined(ENABLE_STATISTICS)
59 # include "vm/statistics.h"
65 #include "vm/jit/asmpart.h"
68 /* class_set_packagename *******************************************************
70 Derive the package name from the class name and store it in the
73 An internal package name consists of the package name plus the
74 trailing '/', e.g. "java/lang/".
76 For classes in the unnamed package, the package name is set to
79 *******************************************************************************/
81 void class_set_packagename(classinfo *c)
86 p = UTF_END(c->name) - 1;
87 start = c->name->text;
89 if (c->name->text[0] == '[') {
90 /* Set packagename of arrays to the element's package. */
92 for (; *start == '['; start++);
94 /* Skip the 'L' in arrays of references. */
100 /* Search for last '/'. */
102 for (; (p > start) && (*p != '/'); --p);
104 /* If we found a '/' we set the package name plus the trailing
105 '/'. Otherwise we set the packagename to NULL. */
108 c->packagename = utf_new(start, p - start + 1);
110 c->packagename = NULL;
114 /* class_create_classinfo ******************************************************
116 Create a new classinfo struct. The class name is set to the given utf *,
117 most other fields are initialized to zero.
119 Note: classname may be NULL. In this case a not-yet-named classinfo is
120 created. The name must be filled in later and class_set_packagename
121 must be called after that.
123 *******************************************************************************/
125 classinfo *class_create_classinfo(utf *classname)
129 #if defined(ENABLE_STATISTICS)
131 size_classinfo += sizeof(classinfo);
134 /* we use a safe name for temporarily unnamed classes */
136 if (classname == NULL)
137 classname = utf_not_named_yet;
141 log_message_utf("Creating class: ", classname);
144 #if !defined(ENABLE_GC_BOEHM)
145 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
146 /*c = NEW(classinfo);
147 MZERO(c, classinfo, 1);*/
149 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
150 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
155 /* Set the header.vftbl of all loaded classes to the one of
156 java.lang.Class, so Java code can use a class as object. */
158 if (class_java_lang_Class != NULL)
159 if (class_java_lang_Class->vftbl != NULL)
160 c->object.header.vftbl = class_java_lang_Class->vftbl;
162 #if defined(ENABLE_JAVASE)
163 /* check if the class is a reference class and flag it */
165 if (classname == utf_java_lang_ref_SoftReference) {
166 c->flags |= ACC_CLASS_REFERENCE_SOFT;
168 else if (classname == utf_java_lang_ref_WeakReference) {
169 c->flags |= ACC_CLASS_REFERENCE_WEAK;
171 else if (classname == utf_java_lang_ref_PhantomReference) {
172 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
176 if (classname != utf_not_named_yet)
177 class_set_packagename(c);
179 LOCK_INIT_OBJECT_LOCK(&c->object.header);
185 /* class_postset_header_vftbl **************************************************
187 Set the header.vftbl of all classes created before java.lang.Class
188 was linked. This is necessary that Java code can use a class as
191 *******************************************************************************/
193 void class_postset_header_vftbl(void)
197 classcache_name_entry *nmen;
198 classcache_class_entry *clsen;
200 assert(class_java_lang_Class);
202 for (slot = 0; slot < hashtable_classcache.size; slot++) {
203 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
205 for (; nmen; nmen = nmen->hashlink) {
206 /* iterate over all class entries */
208 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
211 /* now set the the vftbl */
213 if (c->object.header.vftbl == NULL)
214 c->object.header.vftbl = class_java_lang_Class->vftbl;
220 /* class_define ****************************************************************
222 Calls the loader and defines a class in the VM.
224 *******************************************************************************/
226 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
233 /* check if this class has already been defined */
235 c = classcache_lookup_defined_or_initiated(cl, name);
238 exceptions_throw_linkageerror("duplicate class definition: ", c);
243 /* create a new classinfo struct */
245 c = class_create_classinfo(name);
247 #if defined(ENABLE_STATISTICS)
250 if (opt_getloadingtime)
254 /* build a classbuffer with the given data */
256 cb = NEW(classbuffer);
263 /* preset the defining classloader */
267 /* load the class from this buffer */
269 r = load_class_from_classbuffer(cb);
273 FREE(cb, classbuffer);
275 #if defined(ENABLE_STATISTICS)
278 if (opt_getloadingtime)
283 /* If return value is NULL, we had a problem and the class is
284 not loaded. Now free the allocated memory, otherwise we
285 could run into a DOS. */
292 #if defined(ENABLE_JAVASE)
293 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
294 /* Store the protection domain. */
296 c->protectiondomain = pd;
300 /* Store the newly defined class in the class cache. This call
301 also checks whether a class of the same name has already been
302 defined by the same defining loader, and if so, replaces the
303 newly created class by the one defined earlier. */
305 /* Important: The classinfo given to classcache_store must be
306 fully prepared because another thread may return
307 this pointer after the lookup at to top of this
308 function directly after the class cache lock has
311 c = classcache_store(cl, c, true);
317 /* class_load_attribute_sourcefile *********************************************
319 SourceFile_attribute {
320 u2 attribute_name_index;
325 *******************************************************************************/
327 static bool class_load_attribute_sourcefile(classbuffer *cb)
338 /* check buffer size */
340 if (!suck_check_classbuffer_size(cb, 4 + 2))
343 /* check attribute length */
345 attribute_length = suck_u4(cb);
347 if (attribute_length != 2) {
348 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
352 /* there can be no more than one SourceFile attribute */
354 if (c->sourcefile != NULL) {
355 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
361 sourcefile_index = suck_u2(cb);
362 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
364 if (sourcefile == NULL)
367 /* store sourcefile */
369 c->sourcefile = sourcefile;
375 /* class_load_attribute_enclosingmethod ****************************************
377 EnclosingMethod_attribute {
378 u2 attribute_name_index;
384 *******************************************************************************/
386 #if defined(ENABLE_JAVASE)
387 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
393 classref_or_classinfo cr;
394 constant_nameandtype *cn;
400 /* check buffer size */
402 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
405 /* check attribute length */
407 attribute_length = suck_u4(cb);
409 if (attribute_length != 4) {
410 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
414 /* there can be no more than one EnclosingMethod attribute */
416 if (c->enclosingmethod != NULL) {
417 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
421 /* get class index */
423 class_index = suck_u2(cb);
424 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
426 /* get method index */
428 method_index = suck_u2(cb);
429 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
431 /* store info in classinfo */
433 c->enclosingclass.any = cr.any;
434 c->enclosingmethod = cn;
438 #endif /* defined(ENABLE_JAVASE) */
441 /* class_load_attributes *******************************************************
443 Read attributes from ClassFile.
446 u2 attribute_name_index;
448 u1 info[attribute_length];
451 InnerClasses_attribute {
452 u2 attribute_name_index;
456 *******************************************************************************/
458 bool class_load_attributes(classbuffer *cb)
461 uint16_t attributes_count;
462 uint16_t attribute_name_index;
464 innerclassinfo *info;
465 classref_or_classinfo inner;
466 classref_or_classinfo outer;
473 /* get attributes count */
475 if (!suck_check_classbuffer_size(cb, 2))
478 attributes_count = suck_u2(cb);
480 for (i = 0; i < attributes_count; i++) {
481 /* get attribute name */
483 if (!suck_check_classbuffer_size(cb, 2))
486 attribute_name_index = suck_u2(cb);
488 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
490 if (attribute_name == NULL)
493 if (attribute_name == utf_InnerClasses) {
496 if (c->innerclass != NULL) {
497 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
501 if (!suck_check_classbuffer_size(cb, 4 + 2))
504 /* skip attribute length */
507 /* number of records */
508 c->innerclasscount = suck_u2(cb);
510 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
513 /* allocate memory for innerclass structure */
514 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
516 for (j = 0; j < c->innerclasscount; j++) {
517 /* The innerclass structure contains a class with an encoded
518 name, its defining scope, its simple name and a bitmask of
521 info = c->innerclass + j;
523 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
524 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
525 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
528 /* If the current inner-class is the currently loaded
529 class check for some special flags. */
531 if (inner.ref->name == c->name) {
532 /* If an inner-class is not a member, its
533 outer-class is NULL. */
535 if (outer.ref != NULL) {
536 c->flags |= ACC_CLASS_MEMBER;
538 /* A member class doesn't have an
539 EnclosingMethod attribute, so set the
540 enclosing-class to be the same as the
543 c->declaringclass = outer;
544 c->enclosingclass = outer;
547 /* If an inner-class is anonymous, its name is
551 c->flags |= ACC_CLASS_ANONYMOUS;
554 info->inner_class = inner;
555 info->outer_class = outer;
560 else if (attribute_name == utf_SourceFile) {
563 if (!class_load_attribute_sourcefile(cb))
566 #if defined(ENABLE_JAVASE)
567 else if (attribute_name == utf_EnclosingMethod) {
568 /* EnclosingMethod */
570 if (!class_load_attribute_enclosingmethod(cb))
573 else if (attribute_name == utf_Signature) {
576 if (!loader_load_attribute_signature(cb, &(c->signature)))
581 #if defined(ENABLE_ANNOTATIONS)
582 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
583 /* RuntimeVisibleAnnotations */
584 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
587 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
588 /* RuntimeInvisibleAnnotations */
589 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
595 /* unknown attribute */
597 if (!loader_skip_attribute_body(cb))
606 /* class_freepool **************************************************************
608 Frees all resources used by this classes Constant Pool.
610 *******************************************************************************/
612 static void class_freecpool(classinfo *c)
618 if (c->cptags && c->cpinfos) {
619 for (idx = 0; idx < c->cpcount; idx++) {
620 tag = c->cptags[idx];
621 info = c->cpinfos[idx];
625 case CONSTANT_Fieldref:
626 case CONSTANT_Methodref:
627 case CONSTANT_InterfaceMethodref:
628 FREE(info, constant_FMIref);
630 case CONSTANT_Integer:
631 FREE(info, constant_integer);
634 FREE(info, constant_float);
637 FREE(info, constant_long);
639 case CONSTANT_Double:
640 FREE(info, constant_double);
642 case CONSTANT_NameAndType:
643 FREE(info, constant_nameandtype);
651 MFREE(c->cptags, u1, c->cpcount);
654 MFREE(c->cpinfos, void*, c->cpcount);
658 /* class_getconstant ***********************************************************
660 Retrieves the value at position 'pos' of the constantpool of a
661 class. If the type of the value is other than 'ctype', an error is
664 *******************************************************************************/
666 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
668 /* check index and type of constantpool entry */
669 /* (pos == 0 is caught by type comparison) */
671 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
672 exceptions_throw_classformaterror(c, "Illegal constant pool index");
676 return c->cpinfos[pos];
680 /* innerclass_getconstant ******************************************************
682 Like class_getconstant, but if cptags is ZERO, null is returned.
684 *******************************************************************************/
686 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
688 /* invalid position in constantpool */
690 if (pos >= c->cpcount) {
691 exceptions_throw_classformaterror(c, "Illegal constant pool index");
695 /* constantpool entry of type 0 */
697 if (c->cptags[pos] == 0)
700 /* check type of constantpool entry */
702 if (c->cptags[pos] != ctype) {
703 exceptions_throw_classformaterror(c, "Illegal constant pool index");
707 return c->cpinfos[pos];
711 /* class_free ******************************************************************
713 Frees all resources used by the class.
715 *******************************************************************************/
717 void class_free(classinfo *c)
724 if (c->interfaces != NULL)
725 MFREE(c->interfaces, classinfo*, c->interfacescount);
728 for (i = 0; i < c->fieldscount; i++)
729 field_free(&(c->fields[i]));
730 MFREE(c->fields, fieldinfo, c->fieldscount);
734 for (i = 0; i < c->methodscount; i++)
735 method_free(&(c->methods[i]));
736 MFREE(c->methods, methodinfo, c->methodscount);
739 if ((v = c->vftbl) != NULL) {
741 mem_free(v->arraydesc,sizeof(arraydescriptor));
743 for (i = 0; i < v->interfacetablelength; i++) {
744 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
746 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
748 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
749 sizeof(methodptr*) * (v->interfacetablelength -
750 (v->interfacetablelength > 0));
751 v = (vftbl_t*) (((methodptr*) v) -
752 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
757 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
759 /* if (c->classvftbl)
760 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
766 /* get_array_class *************************************************************
768 Returns the array class with the given name for the given
769 classloader, or NULL if an exception occurred.
771 Note: This function does eager loading.
773 *******************************************************************************/
775 static classinfo *get_array_class(utf *name,classloader_t *initloader,
776 classloader_t *defloader,bool link)
780 /* lookup this class in the classcache */
781 c = classcache_lookup(initloader,name);
783 c = classcache_lookup_defined(defloader,name);
786 /* we have to create it */
787 c = class_create_classinfo(name);
788 c = load_newly_created_array(c,initloader);
794 assert(c->state & CLASS_LOADED);
795 assert(c->classloader == defloader);
797 if (link && !(c->state & CLASS_LINKED))
801 assert(!link || (c->state & CLASS_LINKED));
807 /* class_array_of **************************************************************
809 Returns an array class with the given component class. The array
810 class is dynamically created if neccessary.
812 *******************************************************************************/
814 classinfo *class_array_of(classinfo *component, bool link)
823 cl = component->classloader;
827 /* Assemble the array class name */
828 namelen = component->name->blength;
830 if (component->name->text[0] == '[') {
831 /* the component is itself an array */
832 namebuf = DMNEW(char, namelen + 1);
834 MCOPY(namebuf + 1, component->name->text, char, namelen);
838 /* the component is a non-array class */
839 namebuf = DMNEW(char, namelen + 3);
842 MCOPY(namebuf + 2, component->name->text, char, namelen);
843 namebuf[2 + namelen] = ';';
847 u = utf_new(namebuf, namelen);
849 c = get_array_class(u, cl, cl, link);
857 /* class_multiarray_of *********************************************************
859 Returns an array class with the given dimension and element class.
860 The array class is dynamically created if neccessary.
862 *******************************************************************************/
864 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
874 log_text("Invalid array dimension requested");
878 /* Assemble the array class name */
879 namelen = element->name->blength;
881 if (element->name->text[0] == '[') {
882 /* the element is itself an array */
883 namebuf = DMNEW(char, namelen + dim);
884 memcpy(namebuf + dim, element->name->text, namelen);
888 /* the element is a non-array class */
889 namebuf = DMNEW(char, namelen + 2 + dim);
891 memcpy(namebuf + dim + 1, element->name->text, namelen);
892 namelen += (2 + dim);
893 namebuf[namelen - 1] = ';';
895 memset(namebuf, '[', dim);
897 c = get_array_class(utf_new(namebuf, namelen),
898 element->classloader,
899 element->classloader,
908 /* class_lookup_classref *******************************************************
910 Looks up the constant_classref for a given classname in the classref
914 cls..............the class containing the reference
915 name.............the name of the class refered to
918 a pointer to a constant_classref, or
919 NULL if the reference was not found
921 *******************************************************************************/
923 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
925 constant_classref *ref;
926 extra_classref *xref;
931 assert(!cls->classrefcount || cls->classrefs);
933 /* first search the main classref table */
934 count = cls->classrefcount;
935 ref = cls->classrefs;
936 for (; count; --count, ++ref)
937 if (ref->name == name)
940 /* next try the list of extra classrefs */
941 for (xref = cls->extclassrefs; xref; xref = xref->next) {
942 if (xref->classref.name == name)
943 return &(xref->classref);
951 /* class_get_classref **********************************************************
953 Returns the constant_classref for a given classname.
956 cls..............the class containing the reference
957 name.............the name of the class refered to
960 a pointer to a constant_classref (never NULL)
963 The given name is not checked for validity!
965 *******************************************************************************/
967 constant_classref *class_get_classref(classinfo *cls, utf *name)
969 constant_classref *ref;
970 extra_classref *xref;
975 ref = class_lookup_classref(cls,name);
979 xref = NEW(extra_classref);
980 CLASSREF_INIT(xref->classref,cls,name);
982 xref->next = cls->extclassrefs;
983 cls->extclassrefs = xref;
985 return &(xref->classref);
989 /* class_get_self_classref *****************************************************
991 Returns the constant_classref to the class itself.
994 cls..............the class containing the reference
997 a pointer to a constant_classref (never NULL)
999 *******************************************************************************/
1001 constant_classref *class_get_self_classref(classinfo *cls)
1003 /* XXX this should be done in a faster way. Maybe always make */
1004 /* the classref of index 0 a self reference. */
1005 return class_get_classref(cls,cls->name);
1008 /* class_get_classref_multiarray_of ********************************************
1010 Returns an array type reference with the given dimension and element class
1014 dim..............the requested dimension
1015 dim must be in [1;255]. This is NOT checked!
1016 ref..............the component class reference
1019 a pointer to the class reference for the array type
1022 The referer of `ref` is used as the referer for the new classref.
1024 *******************************************************************************/
1026 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1030 constant_classref *cr;
1034 assert(dim >= 1 && dim <= 255);
1038 /* Assemble the array class name */
1039 namelen = ref->name->blength;
1041 if (ref->name->text[0] == '[') {
1042 /* the element is itself an array */
1043 namebuf = DMNEW(char, namelen + dim);
1044 memcpy(namebuf + dim, ref->name->text, namelen);
1048 /* the element is a non-array class */
1049 namebuf = DMNEW(char, namelen + 2 + dim);
1051 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1052 namelen += (2 + dim);
1053 namebuf[namelen - 1] = ';';
1055 memset(namebuf, '[', dim);
1057 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1065 /* class_get_classref_component_of *********************************************
1067 Returns the component classref of a given array type reference
1070 ref..............the array type reference
1073 a reference to the component class, or
1074 NULL if `ref` is not an object array type reference
1077 The referer of `ref` is used as the referer for the new classref.
1079 *******************************************************************************/
1081 constant_classref *class_get_classref_component_of(constant_classref *ref)
1088 name = ref->name->text;
1092 namelen = ref->name->blength - 1;
1097 else if (*name != '[') {
1101 return class_get_classref(ref->referer, utf_new(name, namelen));
1105 /* class_findmethod ************************************************************
1107 Searches a 'classinfo' structure for a method having the given name
1108 and descriptor. If descriptor is NULL, it is ignored.
1110 *******************************************************************************/
1112 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1117 for (i = 0; i < c->methodscount; i++) {
1118 m = &(c->methods[i]);
1120 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1128 /* class_resolvemethod *********************************************************
1130 Searches a class and it's super classes for a method.
1132 Superinterfaces are *not* searched.
1134 *******************************************************************************/
1136 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1141 m = class_findmethod(c, name, desc);
1146 /* JVM Specification bug:
1148 It is important NOT to resolve special <init> and <clinit>
1149 methods to super classes or interfaces; yet, this is not
1150 explicited in the specification. Section 5.4.3.3 should be
1151 updated appropriately. */
1153 if (name == utf_init || name == utf_clinit)
1163 /* class_resolveinterfacemethod_intern *****************************************
1165 Internally used helper function. Do not use this directly.
1167 *******************************************************************************/
1169 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1170 utf *name, utf *desc)
1175 /* try to find the method in the class */
1177 m = class_findmethod(c, name, desc);
1182 /* No method found? Try the super interfaces. */
1184 for (i = 0; i < c->interfacescount; i++) {
1185 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1191 /* no method found */
1197 /* class_resolveclassmethod ****************************************************
1199 Resolves a reference from REFERER to a method with NAME and DESC in
1202 If the method cannot be resolved the return value is NULL. If
1203 EXCEPT is true *exceptionptr is set, too.
1205 *******************************************************************************/
1207 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1208 classinfo *referer, bool throwexception)
1214 /* if (c->flags & ACC_INTERFACE) { */
1215 /* if (throwexception) */
1216 /* *exceptionptr = */
1217 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1221 /* try class c and its superclasses */
1225 m = class_resolvemethod(cls, name, desc);
1230 /* Try the super interfaces. */
1232 for (i = 0; i < c->interfacescount; i++) {
1233 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1240 exceptions_throw_nosuchmethoderror(c, name, desc);
1245 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1247 exceptions_throw_abstractmethoderror();
1252 /* XXX check access rights */
1258 /* class_resolveinterfacemethod ************************************************
1260 Resolves a reference from REFERER to a method with NAME and DESC in
1263 If the method cannot be resolved the return value is NULL. If
1264 EXCEPT is true *exceptionptr is set, too.
1266 *******************************************************************************/
1268 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1269 classinfo *referer, bool throwexception)
1273 if (!(c->flags & ACC_INTERFACE)) {
1275 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1280 mi = class_resolveinterfacemethod_intern(c, name, desc);
1285 /* try class java.lang.Object */
1287 mi = class_findmethod(class_java_lang_Object, name, desc);
1293 exceptions_throw_nosuchmethoderror(c, name, desc);
1299 /* class_findfield *************************************************************
1301 Searches for field with specified name and type in a classinfo
1302 structure. If no such field is found NULL is returned.
1304 *******************************************************************************/
1306 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1310 for (i = 0; i < c->fieldscount; i++)
1311 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1312 return &(c->fields[i]);
1314 if (c->super != NULL)
1315 return class_findfield(c->super, name, desc);
1321 /* class_findfield_approx ******************************************************
1323 Searches in 'classinfo'-structure for a field with the specified
1326 *******************************************************************************/
1328 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1330 for (int32_t i = 0; i < c->fieldscount; i++) {
1331 fieldinfo* f = &(c->fields[i]);
1333 if (f->name == name)
1338 exceptions_throw_nosuchfielderror(c, name);
1343 /****************** Function: class_resolvefield_int ***************************
1345 This is an internally used helper function. Do not use this directly.
1347 Tries to resolve a field having the given name and type.
1348 If the field cannot be resolved, NULL is returned.
1350 *******************************************************************************/
1352 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1357 /* search for field in class c */
1359 for (i = 0; i < c->fieldscount; i++) {
1360 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1361 return &(c->fields[i]);
1365 /* Try super interfaces recursively. */
1367 for (i = 0; i < c->interfacescount; i++) {
1368 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1374 /* Try super class. */
1376 if (c->super != NULL)
1377 return class_resolvefield_int(c->super, name, desc);
1385 /********************* Function: class_resolvefield ***************************
1387 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1389 If the field cannot be resolved, an exception is thrown and the
1390 return value is NULL.
1392 *******************************************************************************/
1394 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1398 fi = class_resolvefield_int(c, name, desc);
1401 exceptions_throw_nosuchfielderror(c, name);
1405 /* XXX check access rights */
1411 /* class_issubclass ************************************************************
1413 Checks if sub is a descendant of super.
1415 *******************************************************************************/
1417 bool class_issubclass(classinfo *sub, classinfo *super)
1424 /* We reached java/lang/Object and did not find the requested
1430 /* We found the requested super class. */
1440 /* class_isanysubclass *********************************************************
1442 Checks a subclass relation between two classes. Implemented
1443 interfaces are interpreted as super classes.
1445 Return value: 1 ... sub is subclass of super
1448 *******************************************************************************/
1450 bool class_isanysubclass(classinfo *sub, classinfo *super)
1455 /* This is the trivial case. */
1460 /* Primitive classes are only subclasses of themselves. */
1462 if (class_is_primitive(sub) || class_is_primitive(super))
1465 /* Check for interfaces. */
1467 if (super->flags & ACC_INTERFACE) {
1468 result = (sub->vftbl->interfacetablelength > super->index) &&
1469 (sub->vftbl->interfacetable[-super->index] != NULL);
1472 /* java.lang.Object is the only super class of any
1475 if (sub->flags & ACC_INTERFACE)
1476 return (super == class_java_lang_Object);
1478 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1480 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1481 result = diffval <= (uint32_t) super->vftbl->diffval;
1483 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1490 /* class_is_assignable_from ****************************************************
1492 Return whether an instance of the "from" class parameter would be
1493 an instance of this class "to" as well.
1500 true .... is assignable
1501 false ... is not assignable
1503 *******************************************************************************/
1505 bool class_is_assignable_from(classinfo *to, classinfo *from)
1507 if (!(to->state & CLASS_LINKED))
1508 if (!link_class(to))
1511 if (!(from->state & CLASS_LINKED))
1512 if (!link_class(from))
1515 return class_isanysubclass(from, to);
1519 /* class_is_instance ***********************************************************
1521 Return if the given Java object is an instance of the given class.
1528 true .... is instance
1529 false ... is not instance
1531 *******************************************************************************/
1533 bool class_is_instance(classinfo *c, java_handle_t *h)
1535 if (!(c->state & CLASS_LINKED))
1539 return builtin_instanceof(h, c);
1543 /* class_get_componenttype *****************************************************
1545 Return the component class of the given class. If the given class
1546 is not an array, return NULL.
1548 *******************************************************************************/
1550 classinfo *class_get_componenttype(classinfo *c)
1552 classinfo *component;
1553 arraydescriptor *ad;
1555 /* XXX maybe we could find a way to do this without linking. */
1556 /* This way should be safe and easy, however. */
1558 if (!(c->state & CLASS_LINKED))
1562 ad = c->vftbl->arraydesc;
1567 if (ad->arraytype == ARRAYTYPE_OBJECT)
1568 component = ad->componentvftbl->clazz;
1570 component = Primitive_get_class_by_type(ad->arraytype);
1576 /* class_get_declaredclasses ***************************************************
1578 Return an array of declared classes of the given class.
1580 *******************************************************************************/
1582 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1584 classref_or_classinfo inner;
1585 classref_or_classinfo outer;
1587 int declaredclasscount; /* number of declared classes */
1588 int pos; /* current declared class */
1589 java_handle_objectarray_t *oa; /* array of declared classes */
1593 declaredclasscount = 0;
1595 if (!class_is_primitive(c) && !class_is_array(c)) {
1596 /* Determine number of declared classes. */
1598 for (i = 0; i < c->innerclasscount; i++) {
1599 /* Get outer-class. If the inner-class is not a member
1600 class, the outer-class is NULL. */
1602 outer = c->innerclass[i].outer_class;
1604 if (outer.any == NULL)
1607 /* Check if outer-class is a classref or a real class and
1608 get the class name from the structure. */
1610 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1612 /* Outer class is this class. */
1614 if ((outername == c->name) &&
1615 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1616 declaredclasscount++;
1620 /* Allocate Class[] and check for OOM. */
1622 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1627 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1628 inner = c->innerclass[i].inner_class;
1629 outer = c->innerclass[i].outer_class;
1631 /* Get outer-class. If the inner-class is not a member class,
1632 the outer-class is NULL. */
1634 if (outer.any == NULL)
1637 /* Check if outer_class is a classref or a real class and get
1638 the class name from the structure. */
1640 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1642 /* Outer class is this class. */
1644 if ((outername == c->name) &&
1645 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1647 ic = resolve_classref_or_classinfo_eager(inner, false);
1652 if (!(ic->state & CLASS_LINKED))
1653 if (!link_class(ic))
1656 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1665 * Return an array of declared constructors of the given class.
1667 * @param c class to get the constructors of
1668 * @param publicOnly show only public fields
1670 * @return array of java.lang.reflect.Constructor
1672 #if defined(ENABLE_JAVASE)
1673 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1676 java_handle_objectarray_t* oa;
1682 /* Determine number of constructors. */
1686 for (i = 0; i < c->methodscount; i++) {
1687 m = &(c->methods[i]);
1689 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1690 (m->name == utf_init))
1694 /* Create array of constructors. */
1696 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1701 /* Get the constructors and store them in the array. */
1703 for (i = 0, index = 0; i < c->methodscount; i++) {
1704 m = &(c->methods[i]);
1706 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1707 (m->name == utf_init)) {
1708 // Create a java.lang.reflect.Constructor object.
1710 rc = java_lang_reflect_Constructor_create(m);
1712 /* Store object into array. */
1714 array_objectarray_element_set(oa, index, rc);
1724 /* class_get_declaredfields ****************************************************
1726 Return an array of declared fields of the given class.
1729 c ............ class to get the fields of
1730 publicOnly ... show only public fields
1733 array of java.lang.reflect.Field
1735 *******************************************************************************/
1737 #if defined(ENABLE_JAVASE)
1738 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1740 java_handle_objectarray_t *oa;
1747 /* Determine number of fields. */
1751 for (i = 0; i < c->fieldscount; i++)
1752 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1755 /* Create array of fields. */
1757 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1762 /* Get the fields and store them in the array. */
1764 for (i = 0, index = 0; i < c->fieldscount; i++) {
1765 f = &(c->fields[i]);
1767 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1768 // Create a java.lang.reflect.Field object.
1770 h = java_lang_reflect_Field_create(f);
1772 /* Store object into array. */
1774 array_objectarray_element_set(oa, index, h);
1784 /* class_get_declaredmethods ***************************************************
1786 Return an array of declared methods of the given class.
1789 c ............ class to get the methods of
1790 publicOnly ... show only public methods
1793 array of java.lang.reflect.Method
1795 *******************************************************************************/
1797 #if defined(ENABLE_JAVASE)
1798 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1800 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1801 methodinfo *m; /* the current method to be represented */
1807 /* JOWENN: array classes do not declare methods according to mauve
1808 test. It should be considered, if we should return to my old
1809 clone method overriding instead of declaring it as a member
1812 if (class_is_array(c))
1813 return builtin_anewarray(0, class_java_lang_reflect_Method);
1815 /* Determine number of methods. */
1819 for (i = 0; i < c->methodscount; i++) {
1820 m = &(c->methods[i]);
1822 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1823 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1824 !(m->flags & ACC_MIRANDA))
1828 /* Create array of methods. */
1830 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1835 /* Get the methods and store them in the array. */
1837 for (i = 0, index = 0; i < c->methodscount; i++) {
1838 m = &(c->methods[i]);
1840 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1841 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1842 !(m->flags & ACC_MIRANDA)) {
1843 // Create java.lang.reflect.Method object.
1845 h = java_lang_reflect_Method_create(m);
1847 /* Store object into array. */
1849 array_objectarray_element_set(oa, index, h);
1859 /* class_get_declaringclass ****************************************************
1861 If the class or interface given is a member of another class,
1862 return the declaring class. For array and primitive classes return
1865 *******************************************************************************/
1867 classinfo *class_get_declaringclass(classinfo *c)
1869 classref_or_classinfo cr;
1872 /* Get declaring class. */
1874 cr = c->declaringclass;
1879 /* Resolve the class if necessary. */
1881 if (IS_CLASSREF(cr)) {
1882 /* dc = resolve_classref_eager(cr.ref); */
1883 dc = resolve_classref_or_classinfo_eager(cr, true);
1888 /* Store the resolved class in the class structure. */
1899 /* class_get_enclosingclass ****************************************************
1901 Return the enclosing class for the given class.
1903 *******************************************************************************/
1905 classinfo *class_get_enclosingclass(classinfo *c)
1907 classref_or_classinfo cr;
1910 /* Get enclosing class. */
1912 cr = c->enclosingclass;
1917 /* Resolve the class if necessary. */
1919 if (IS_CLASSREF(cr)) {
1920 /* ec = resolve_classref_eager(cr.ref); */
1921 ec = resolve_classref_or_classinfo_eager(cr, true);
1926 /* Store the resolved class in the class structure. */
1938 * Return the enclosing constructor as java.lang.reflect.Constructor
1939 * object for the given class.
1941 * @param c class to return the enclosing constructor for
1943 * @return java.lang.reflect.Constructor object of the enclosing
1946 #if defined(ENABLE_JAVASE)
1947 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1952 m = class_get_enclosingmethod_raw(c);
1957 /* Check for <init>. */
1959 if (m->name != utf_init)
1962 // Create a java.lang.reflect.Constructor object.
1964 rc = java_lang_reflect_Constructor_create(m);
1971 /* class_get_enclosingmethod ***************************************************
1973 Return the enclosing method for the given class.
1976 c ... class to return the enclosing method for
1979 methodinfo of the enclosing method
1981 *******************************************************************************/
1983 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1985 constant_nameandtype *cn;
1989 /* get enclosing class and method */
1991 ec = class_get_enclosingclass(c);
1992 cn = c->enclosingmethod;
1994 /* check for enclosing class and method */
2002 /* find method in enclosing class */
2004 m = class_findmethod(ec, cn->name, cn->descriptor);
2007 exceptions_throw_internalerror("Enclosing method doesn't exist");
2016 * Return the enclosing method as java.lang.reflect.Method object for
2019 * @param c class to return the enclosing method for
2021 * @return java.lang.reflect.Method object of the enclosing method
2023 #if defined(ENABLE_JAVASE)
2024 java_handle_t* class_get_enclosingmethod(classinfo *c)
2029 m = class_get_enclosingmethod_raw(c);
2034 /* check for <init> */
2036 if (m->name == utf_init)
2039 // Create a java.lang.reflect.Method object.
2041 rm = java_lang_reflect_Method_create(m);
2048 /* class_get_interfaces ********************************************************
2050 Return an array of interfaces of the given class.
2052 *******************************************************************************/
2054 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2057 java_handle_objectarray_t *oa;
2060 if (!(c->state & CLASS_LINKED))
2064 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2069 for (i = 0; i < c->interfacescount; i++) {
2070 ic = c->interfaces[i];
2072 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2079 /* class_get_annotations *******************************************************
2081 Get the unparsed declared annotations in a byte array
2085 c........the class of which the annotations should be returned
2088 The unparsed declared annotations in a byte array
2089 (or NULL if there aren't any).
2091 *******************************************************************************/
2093 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2095 #if defined(ENABLE_ANNOTATIONS)
2096 java_handle_t *annotations; /* unparsed annotations */
2098 LLNI_classinfo_field_get(c, annotations, annotations);
2100 return (java_handle_bytearray_t*)annotations;
2107 /* class_get_modifiers *********************************************************
2109 Get the modifier flags of the given class.
2112 c....the class of which the modifier flags should be returned
2113 ignoreInnerClassesAttrib
2117 *******************************************************************************/
2119 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2121 classref_or_classinfo inner;
2122 classref_or_classinfo outer;
2126 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2127 /* search for passed class as inner class */
2129 for (i = 0; i < c->innerclasscount; i++) {
2130 inner = c->innerclass[i].inner_class;
2131 outer = c->innerclass[i].outer_class;
2133 /* Check if inner is a classref or a real class and get
2134 the name of the structure */
2136 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2138 /* innerclass is this class */
2140 if (innername == c->name) {
2141 /* has the class actually an outer class? */
2144 /* return flags got from the outer class file */
2145 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2147 return c->flags & ACC_CLASS_REFLECT_MASK;
2152 /* passed class is no inner class or it was not requested */
2154 return c->flags & ACC_CLASS_REFLECT_MASK;
2158 /* class_get_signature *********************************************************
2160 Return the signature of the given class. For array and primitive
2161 classes return NULL.
2163 *******************************************************************************/
2165 #if defined(ENABLE_JAVASE)
2166 utf *class_get_signature(classinfo *c)
2168 /* For array and primitive classes return NULL. */
2170 if (class_is_array(c) || class_is_primitive(c))
2173 return c->signature;
2178 /* class_printflags ************************************************************
2180 Prints flags of a class.
2182 *******************************************************************************/
2184 #if !defined(NDEBUG)
2185 void class_printflags(classinfo *c)
2192 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2193 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2194 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2195 if (c->flags & ACC_STATIC) printf(" STATIC");
2196 if (c->flags & ACC_FINAL) printf(" FINAL");
2197 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2198 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2199 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2200 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2201 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2202 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2207 /* class_print *****************************************************************
2209 Prints classname plus flags.
2211 *******************************************************************************/
2213 #if !defined(NDEBUG)
2214 void class_print(classinfo *c)
2221 utf_display_printable_ascii(c->name);
2222 class_printflags(c);
2227 /* class_classref_print ********************************************************
2229 Prints classname plus referer class.
2231 *******************************************************************************/
2233 #if !defined(NDEBUG)
2234 void class_classref_print(constant_classref *cr)
2241 utf_display_printable_ascii(cr->name);
2244 class_print(cr->referer);
2252 /* class_println ***************************************************************
2254 Prints classname plus flags and new line.
2256 *******************************************************************************/
2258 #if !defined(NDEBUG)
2259 void class_println(classinfo *c)
2267 /* class_classref_println ******************************************************
2269 Prints classname plus referer class and new line.
2271 *******************************************************************************/
2273 #if !defined(NDEBUG)
2274 void class_classref_println(constant_classref *cr)
2276 class_classref_print(cr);
2282 /* class_classref_or_classinfo_print *******************************************
2284 Prints classname plus referer class.
2286 *******************************************************************************/
2288 #if !defined(NDEBUG)
2289 void class_classref_or_classinfo_print(classref_or_classinfo c)
2291 if (c.any == NULL) {
2292 printf("(classref_or_classinfo) NULL");
2296 class_classref_print(c.ref);
2303 /* class_classref_or_classinfo_println *****************************************
2305 Prints classname plus referer class and a newline.
2307 *******************************************************************************/
2309 #if !defined(NDEBUG)
2310 void class_classref_or_classinfo_println(classref_or_classinfo c)
2312 class_classref_or_classinfo_print(c);
2318 /* class_showconstantpool ******************************************************
2320 Dump the constant pool of the given class to stdout.
2322 *******************************************************************************/
2324 #if !defined(NDEBUG)
2325 void class_showconstantpool (classinfo *c)
2330 printf ("---- dump of constant pool ----\n");
2332 for (i=0; i<c->cpcount; i++) {
2333 printf ("#%d: ", (int) i);
2335 e = c -> cpinfos [i];
2338 switch (c -> cptags [i]) {
2339 case CONSTANT_Class:
2340 printf ("Classreference -> ");
2341 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2343 case CONSTANT_Fieldref:
2344 printf ("Fieldref -> ");
2345 field_fieldref_print((constant_FMIref *) e);
2347 case CONSTANT_Methodref:
2348 printf ("Methodref -> ");
2349 method_methodref_print((constant_FMIref *) e);
2351 case CONSTANT_InterfaceMethodref:
2352 printf ("InterfaceMethod -> ");
2353 method_methodref_print((constant_FMIref *) e);
2355 case CONSTANT_String:
2356 printf ("String -> ");
2357 utf_display_printable_ascii (e);
2359 case CONSTANT_Integer:
2360 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2362 case CONSTANT_Float:
2363 printf ("Float -> %f", ((constant_float*)e) -> value);
2365 case CONSTANT_Double:
2366 printf ("Double -> %f", ((constant_double*)e) -> value);
2370 u8 v = ((constant_long*)e) -> value;
2372 printf ("Long -> %ld", (long int) v);
2374 printf ("Long -> HI: %ld, LO: %ld\n",
2375 (long int) v.high, (long int) v.low);
2379 case CONSTANT_NameAndType:
2381 constant_nameandtype *cnt = e;
2382 printf ("NameAndType: ");
2383 utf_display_printable_ascii (cnt->name);
2385 utf_display_printable_ascii (cnt->descriptor);
2389 printf ("Utf8 -> ");
2390 utf_display_printable_ascii (e);
2393 log_text("Invalid type of ConstantPool-Entry");
2401 #endif /* !defined(NDEBUG) */
2404 /* class_showmethods ***********************************************************
2406 Dump info about the fields and methods of the given class to stdout.
2408 *******************************************************************************/
2410 #if !defined(NDEBUG)
2411 void class_showmethods (classinfo *c)
2415 printf("--------- Fields and Methods ----------------\n");
2417 class_printflags(c);
2421 utf_display_printable_ascii(c->name);
2426 utf_display_printable_ascii(c->super->name);
2430 printf("Index: %d\n", c->index);
2432 printf("Interfaces:\n");
2433 for (i = 0; i < c->interfacescount; i++) {
2435 utf_display_printable_ascii(c->interfaces[i]->name);
2436 printf (" (%d)\n", c->interfaces[i]->index);
2439 printf("Fields:\n");
2440 for (i = 0; i < c->fieldscount; i++)
2441 field_println(&(c->fields[i]));
2443 printf("Methods:\n");
2444 for (i = 0; i < c->methodscount; i++) {
2445 methodinfo *m = &(c->methods[i]);
2447 if (!(m->flags & ACC_STATIC))
2448 printf("vftblindex: %d ", m->vftblindex);
2453 printf ("Virtual function table:\n");
2454 for (i = 0; i < c->vftbl->vftbllength; i++)
2455 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2457 #endif /* !defined(NDEBUG) */
2461 * These are local overrides for various environment variables in Emacs.
2462 * Please do not remove this and leave it at the end of the file, where
2463 * Emacs will automagically detect them.
2464 * ---------------------------------------------------------------------
2467 * indent-tabs-mode: t
2471 * vim:noexpandtab:sw=4:ts=4: