Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vmcore / class.c
1 /* src/vmcore/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: class.c 7918 2007-05-20 20:42:18Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "vm/types.h"
38
39 #include "arch.h"
40
41 #include "mm/memory.h"
42
43 #include "threads/lock-common.h"
44
45 #include "toolbox/logging.h"
46
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49
50 #include "vm/jit/asmpart.h"
51
52 #include "vmcore/class.h"
53 #include "vmcore/classcache.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/options.h"
56
57 #if defined(ENABLE_STATISTICS)
58 # include "vmcore/statistics.h"
59 #endif
60
61 #include "vmcore/suck.h"
62 #include "vmcore/utf8.h"
63
64
65 /* global variables ***********************************************************/
66
67 list_t unlinkedclasses;                 /* this is only used for eager class  */
68                                         /* loading                            */
69
70
71 /* frequently used classes ****************************************************/
72
73 /* important system classes */
74
75 classinfo *class_java_lang_Object;
76 classinfo *class_java_lang_Class;
77 classinfo *class_java_lang_ClassLoader;
78 classinfo *class_java_lang_Cloneable;
79 classinfo *class_java_lang_SecurityManager;
80 classinfo *class_java_lang_String;
81 classinfo *class_java_lang_System;
82 classinfo *class_java_lang_Thread;
83 classinfo *class_java_lang_ThreadGroup;
84 classinfo *class_java_lang_VMSystem;
85 classinfo *class_java_lang_VMThread;
86 classinfo *class_java_io_Serializable;
87
88
89 /* system exception classes required in cacao */
90
91 classinfo *class_java_lang_Throwable;
92 classinfo *class_java_lang_Error;
93 classinfo *class_java_lang_LinkageError;
94 classinfo *class_java_lang_NoClassDefFoundError;
95 classinfo *class_java_lang_OutOfMemoryError;
96 classinfo *class_java_lang_VirtualMachineError;
97
98 #if defined(WITH_CLASSPATH_GNU)
99 classinfo *class_java_lang_VMThrowable;
100 #endif
101
102 classinfo *class_java_lang_Exception;
103 classinfo *class_java_lang_ClassCastException;
104 classinfo *class_java_lang_ClassNotFoundException;
105
106 #if defined(ENABLE_JAVASE)
107 classinfo *class_java_lang_Void;
108 #endif
109 classinfo *class_java_lang_Boolean;
110 classinfo *class_java_lang_Byte;
111 classinfo *class_java_lang_Character;
112 classinfo *class_java_lang_Short;
113 classinfo *class_java_lang_Integer;
114 classinfo *class_java_lang_Long;
115 classinfo *class_java_lang_Float;
116 classinfo *class_java_lang_Double;
117
118
119 /* some runtime exception */
120
121 classinfo *class_java_lang_NullPointerException;
122
123
124 /* some classes which may be used more often */
125
126 #if defined(ENABLE_JAVASE)
127 classinfo *class_java_lang_StackTraceElement;
128 classinfo *class_java_lang_reflect_Constructor;
129 classinfo *class_java_lang_reflect_Field;
130 classinfo *class_java_lang_reflect_Method;
131 classinfo *class_java_security_PrivilegedAction;
132 classinfo *class_java_util_Vector;
133
134 classinfo *arrayclass_java_lang_Object;
135 #endif
136
137
138 /* pseudo classes for the typechecker */
139
140 classinfo *pseudo_class_Arraystub;
141 classinfo *pseudo_class_Null;
142 classinfo *pseudo_class_New;
143
144
145 /* class_set_packagename *******************************************************
146
147    Derive the package name from the class name and store it in the struct.
148
149 *******************************************************************************/
150
151 void class_set_packagename(classinfo *c)
152 {
153         char *p = UTF_END(c->name) - 1;
154         char *start = c->name->text;
155
156         /* set the package name */
157         /* classes in the unnamed package keep packagename == NULL */
158
159         if (c->name->text[0] == '[') {
160                 /* set packagename of arrays to the element's package */
161
162                 for (; *start == '['; start++);
163
164                 /* skip the 'L' in arrays of references */
165                 if (*start == 'L')
166                         start++;
167
168                 for (; (p > start) && (*p != '/'); --p);
169
170                 c->packagename = utf_new(start, p - start);
171
172         } else {
173                 for (; (p > start) && (*p != '/'); --p);
174
175                 c->packagename = utf_new(start, p - start);
176         }
177 }
178
179
180 /* class_create_classinfo ******************************************************
181
182    Create a new classinfo struct. The class name is set to the given utf *,
183    most other fields are initialized to zero.
184
185    Note: classname may be NULL. In this case a not-yet-named classinfo is
186          created. The name must be filled in later and class_set_packagename
187                  must be called after that.
188
189 *******************************************************************************/
190
191 classinfo *class_create_classinfo(utf *classname)
192 {
193         classinfo *c;
194
195 #if defined(ENABLE_STATISTICS)
196         if (opt_stat)
197                 size_classinfo += sizeof(classinfo);
198 #endif
199
200         /* we use a safe name for temporarily unnamed classes */
201
202         if (classname == NULL)
203                 classname = utf_not_named_yet;
204
205 #if !defined(NDEBUG)
206         if (initverbose)
207                 log_message_utf("Creating class: ", classname);
208 #endif
209
210         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
211
212 #if defined(ENABLE_GC_CACAO)
213         c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
214 #else
215         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
216         /*c=NEW(classinfo);*/
217 #endif
218         c->name = classname;
219
220         /* Set the header.vftbl of all loaded classes to the one of
221        java.lang.Class, so Java code can use a class as object. */
222
223         if (class_java_lang_Class != NULL)
224                 if (class_java_lang_Class->vftbl != NULL)
225                         c->object.header.vftbl = class_java_lang_Class->vftbl;
226
227 #if defined(ENABLE_JAVASE)
228         /* check if the class is a reference class and flag it */
229
230         if (classname == utf_java_lang_ref_SoftReference) {
231                 c->flags |= ACC_CLASS_SOFT_REFERENCE;
232         }
233         else if (classname == utf_java_lang_ref_WeakReference) {
234                 c->flags |= ACC_CLASS_WEAK_REFERENCE;
235         }
236         else if (classname == utf_java_lang_ref_PhantomReference) {
237                 c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
238         }
239 #endif
240
241         if (classname != utf_not_named_yet)
242                 class_set_packagename(c);
243
244         LOCK_INIT_OBJECT_LOCK(&c->object.header);
245
246         return c;
247 }
248
249
250 /* class_postset_header_vftbl **************************************************
251
252    Set the header.vftbl of all classes created before java.lang.Class
253    was linked.  This is necessary that Java code can use a class as
254    object.
255
256 *******************************************************************************/
257
258 void class_postset_header_vftbl(void)
259 {
260         classinfo *c;
261         u4 slot;
262         classcache_name_entry *nmen;
263         classcache_class_entry *clsen;
264
265         assert(class_java_lang_Class);
266
267         for (slot = 0; slot < hashtable_classcache.size; slot++) {
268                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
269
270                 for (; nmen; nmen = nmen->hashlink) {
271                         /* iterate over all class entries */
272
273                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
274                                 c = clsen->classobj;
275
276                                 /* now set the the vftbl */
277
278                                 if (c->object.header.vftbl == NULL)
279                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
280                         }
281                 }
282         }
283 }
284
285
286 /* class_load_attribute_sourcefile *********************************************
287
288    SourceFile_attribute {
289        u2 attribute_name_index;
290        u4 attribute_length;
291            u2 sourcefile_index;
292    }
293
294 *******************************************************************************/
295
296 static bool class_load_attribute_sourcefile(classbuffer *cb)
297 {
298         classinfo *c;
299         u4         attribute_length;
300         u2         sourcefile_index;
301         utf       *sourcefile;
302
303         /* get classinfo */
304
305         c = cb->class;
306
307         /* check buffer size */
308
309         if (!suck_check_classbuffer_size(cb, 4 + 2))
310                 return false;
311
312         /* check attribute length */
313
314         attribute_length = suck_u4(cb);
315
316         if (attribute_length != 2) {
317                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
318                 return false;
319         }
320
321         /* there can be no more than one SourceFile attribute */
322
323         if (c->sourcefile != NULL) {
324                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
325                 return false;
326         }
327
328         /* get sourcefile */
329
330         sourcefile_index = suck_u2(cb);
331         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
332
333         if (sourcefile == NULL)
334                 return false;
335
336         /* store sourcefile */
337
338         c->sourcefile = sourcefile;
339
340         return true;
341 }
342
343
344 /* class_load_attribute_enclosingmethod ****************************************
345
346    EnclosingMethod_attribute {
347        u2 attribute_name_index;
348        u4 attribute_length;
349            u2 class_index;
350            u2 method_index;
351    }
352
353 *******************************************************************************/
354
355 #if defined(ENABLE_JAVASE)
356 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
357 {
358         classinfo             *c;
359         u4                     attribute_length;
360         u2                     class_index;
361         u2                     method_index;
362         classref_or_classinfo  cr;
363         constant_nameandtype  *cn;
364
365         /* get classinfo */
366
367         c = cb->class;
368
369         /* check buffer size */
370
371         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
372                 return false;
373
374         /* check attribute length */
375
376         attribute_length = suck_u4(cb);
377
378         if (attribute_length != 4) {
379                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
380                 return false;
381         }
382
383         /* there can be no more than one EnclosingMethod attribute */
384
385         if (c->enclosingmethod != NULL) {
386                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
387                 return false;
388         }
389
390         /* get class index */
391
392         class_index = suck_u2(cb);
393         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
394
395         /* get method index */
396
397         method_index = suck_u2(cb);
398         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
399
400         /* store info in classinfo */
401
402         c->enclosingclass.any = cr.any;
403         c->enclosingmethod    = cn;
404
405         return true;
406 }
407 #endif /* defined(ENABLE_JAVASE) */
408
409
410 /* class_load_attributes *******************************************************
411
412    Read attributes from ClassFile.
413
414    attribute_info {
415        u2 attribute_name_index;
416        u4 attribute_length;
417        u1 info[attribute_length];
418    }
419
420    InnerClasses_attribute {
421        u2 attribute_name_index;
422        u4 attribute_length;
423    }
424
425 *******************************************************************************/
426
427 bool class_load_attributes(classbuffer *cb)
428 {
429         classinfo *c;
430         u4         i, j;
431         u2         attributes_count;
432         u2         attribute_name_index;
433         utf       *attribute_name;
434
435         c = cb->class;
436
437         /* get attributes count */
438
439         if (!suck_check_classbuffer_size(cb, 2))
440                 return false;
441
442         attributes_count = suck_u2(cb);
443
444         for (i = 0; i < attributes_count; i++) {
445                 /* get attribute name */
446
447                 if (!suck_check_classbuffer_size(cb, 2))
448                         return false;
449
450                 attribute_name_index = suck_u2(cb);
451                 attribute_name =
452                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
453
454                 if (attribute_name == NULL)
455                         return false;
456
457                 if (attribute_name == utf_InnerClasses) {
458                         /* InnerClasses */
459
460                         if (c->innerclass != NULL) {
461                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
462                                 return false;
463                         }
464                                 
465                         if (!suck_check_classbuffer_size(cb, 4 + 2))
466                                 return false;
467
468                         /* skip attribute length */
469                         suck_u4(cb);
470
471                         /* number of records */
472                         c->innerclasscount = suck_u2(cb);
473
474                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
475                                 return false;
476
477                         /* allocate memory for innerclass structure */
478                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
479
480                         for (j = 0; j < c->innerclasscount; j++) {
481                                 /* The innerclass structure contains a class with an encoded
482                                    name, its defining scope, its simple name and a bitmask of
483                                    the access flags. If an inner class is not a member, its
484                                    outer_class is NULL, if a class is anonymous, its name is
485                                    NULL. */
486                                                                 
487                                 innerclassinfo *info = c->innerclass + j;
488
489                                 info->inner_class.ref =
490                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
491                                 info->outer_class.ref =
492                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
493                                 info->name =
494                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
495                                 info->flags = suck_u2(cb);
496                         }
497                 }
498                 else if (attribute_name == utf_SourceFile) {
499                         /* SourceFile */
500
501                         if (!class_load_attribute_sourcefile(cb))
502                                 return false;
503                 }
504 #if defined(ENABLE_JAVASE)
505                 else if (attribute_name == utf_EnclosingMethod) {
506                         /* EnclosingMethod */
507
508                         if (!class_load_attribute_enclosingmethod(cb))
509                                 return false;
510                 }
511                 else if (attribute_name == utf_Signature) {
512                         /* Signature */
513
514                         if (!loader_load_attribute_signature(cb, &(c->signature)))
515                                 return false;
516                 }
517 #if 0
518                 /* XXX We can't do a release with that enabled */
519
520                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
521                         /* RuntimeVisibleAnnotations */
522
523                         if (!annotation_load_attribute_runtimevisibleannotations(cb))
524                                 return false;
525                 }
526 #endif
527 #endif
528                 else {
529                         /* unknown attribute */
530
531                         if (!loader_skip_attribute_body(cb))
532                                 return false;
533                 }
534         }
535
536         return true;
537 }
538
539
540 /* class_freepool **************************************************************
541
542         Frees all resources used by this classes Constant Pool.
543
544 *******************************************************************************/
545
546 static void class_freecpool(classinfo *c)
547 {
548         u4 idx;
549         u4 tag;
550         voidptr info;
551         
552         if (c->cptags && c->cpinfos) {
553                 for (idx = 0; idx < c->cpcount; idx++) {
554                         tag = c->cptags[idx];
555                         info = c->cpinfos[idx];
556                 
557                         if (info != NULL) {
558                                 switch (tag) {
559                                 case CONSTANT_Fieldref:
560                                 case CONSTANT_Methodref:
561                                 case CONSTANT_InterfaceMethodref:
562                                         FREE(info, constant_FMIref);
563                                         break;
564                                 case CONSTANT_Integer:
565                                         FREE(info, constant_integer);
566                                         break;
567                                 case CONSTANT_Float:
568                                         FREE(info, constant_float);
569                                         break;
570                                 case CONSTANT_Long:
571                                         FREE(info, constant_long);
572                                         break;
573                                 case CONSTANT_Double:
574                                         FREE(info, constant_double);
575                                         break;
576                                 case CONSTANT_NameAndType:
577                                         FREE(info, constant_nameandtype);
578                                         break;
579                                 }
580                         }
581                 }
582         }
583
584         if (c->cptags)
585                 MFREE(c->cptags, u1, c->cpcount);
586
587         if (c->cpinfos)
588                 MFREE(c->cpinfos, voidptr, c->cpcount);
589 }
590
591
592 /* class_getconstant ***********************************************************
593
594    Retrieves the value at position 'pos' of the constantpool of a
595    class. If the type of the value is other than 'ctype', an error is
596    thrown.
597
598 *******************************************************************************/
599
600 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
601 {
602         /* check index and type of constantpool entry */
603         /* (pos == 0 is caught by type comparison) */
604
605         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
606                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
607                 return NULL;
608         }
609
610         return c->cpinfos[pos];
611 }
612
613
614 /* innerclass_getconstant ******************************************************
615
616    Like class_getconstant, but if cptags is ZERO, null is returned.
617         
618 *******************************************************************************/
619
620 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
621 {
622         /* invalid position in constantpool */
623
624         if (pos >= c->cpcount) {
625                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
626                 return NULL;
627         }
628
629         /* constantpool entry of type 0 */      
630
631         if (c->cptags[pos] == 0)
632                 return NULL;
633
634         /* check type of constantpool entry */
635
636         if (c->cptags[pos] != ctype) {
637                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
638                 return NULL;
639         }
640                 
641         return c->cpinfos[pos];
642 }
643
644
645 /* class_free ******************************************************************
646
647    Frees all resources used by the class.
648
649 *******************************************************************************/
650
651 void class_free(classinfo *c)
652 {
653         s4 i;
654         vftbl_t *v;
655                 
656         class_freecpool(c);
657
658         if (c->interfaces)
659                 MFREE(c->interfaces, classinfo*, c->interfacescount);
660
661         if (c->fields) {
662                 for (i = 0; i < c->fieldscount; i++)
663                         field_free(&(c->fields[i]));
664 #if defined(ENABLE_CACAO_GC)
665                 MFREE(c->fields, fieldinfo, c->fieldscount);
666 #endif
667         }
668         
669         if (c->methods) {
670                 for (i = 0; i < c->methodscount; i++)
671                         method_free(&(c->methods[i]));
672                 MFREE(c->methods, methodinfo, c->methodscount);
673         }
674
675         if ((v = c->vftbl) != NULL) {
676                 if (v->arraydesc)
677                         mem_free(v->arraydesc,sizeof(arraydescriptor));
678                 
679                 for (i = 0; i < v->interfacetablelength; i++) {
680                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
681                 }
682                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
683
684                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
685                     sizeof(methodptr*) * (v->interfacetablelength -
686                                          (v->interfacetablelength > 0));
687                 v = (vftbl_t*) (((methodptr*) v) -
688                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
689                 mem_free(v, i);
690         }
691
692         if (c->innerclass)
693                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
694
695         /*      if (c->classvftbl)
696                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
697         
698 /*      GCFREE(c); */
699 }
700
701
702 /* get_array_class *************************************************************
703
704    Returns the array class with the given name for the given
705    classloader, or NULL if an exception occurred.
706
707    Note: This function does eager loading. 
708
709 *******************************************************************************/
710
711 static classinfo *get_array_class(utf *name,classloader *initloader,
712                                                                                         classloader *defloader,bool link)
713 {
714         classinfo *c;
715         
716         /* lookup this class in the classcache */
717         c = classcache_lookup(initloader,name);
718         if (!c)
719                 c = classcache_lookup_defined(defloader,name);
720
721         if (!c) {
722                 /* we have to create it */
723                 c = class_create_classinfo(name);
724                 c = load_newly_created_array(c,initloader);
725                 if (c == NULL)
726                         return NULL;
727         }
728
729         assert(c);
730         assert(c->state & CLASS_LOADED);
731         assert(c->classloader == defloader);
732
733         if (link && !(c->state & CLASS_LINKED))
734                 if (!link_class(c))
735                         return NULL;
736
737         assert(!link || (c->state & CLASS_LINKED));
738
739         return c;
740 }
741
742
743 /* class_array_of **************************************************************
744
745    Returns an array class with the given component class. The array
746    class is dynamically created if neccessary.
747
748 *******************************************************************************/
749
750 classinfo *class_array_of(classinfo *component, bool link)
751 {
752     s4 namelen;
753     char *namebuf;
754         s4 dumpsize;
755         classinfo *c;
756
757         dumpsize = dump_size();
758
759     /* Assemble the array class name */
760     namelen = component->name->blength;
761     
762     if (component->name->text[0] == '[') {
763         /* the component is itself an array */
764         namebuf = DMNEW(char, namelen + 1);
765         namebuf[0] = '[';
766         MCOPY(namebuf + 1, component->name->text, char, namelen);
767         namelen++;
768
769     } else {
770         /* the component is a non-array class */
771         namebuf = DMNEW(char, namelen + 3);
772         namebuf[0] = '[';
773         namebuf[1] = 'L';
774         MCOPY(namebuf + 2, component->name->text, char, namelen);
775         namebuf[2 + namelen] = ';';
776         namelen += 3;
777     }
778
779         c = get_array_class(utf_new(namebuf, namelen),
780                                                 component->classloader,
781                                                 component->classloader,
782                                                 link);
783
784         dump_release(dumpsize);
785
786         return c;
787 }
788
789
790 /* class_multiarray_of *********************************************************
791
792    Returns an array class with the given dimension and element class.
793    The array class is dynamically created if neccessary.
794
795 *******************************************************************************/
796
797 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
798 {
799     s4 namelen;
800     char *namebuf;
801         s4 dumpsize;
802         classinfo *c;
803
804         dumpsize = dump_size();
805
806         if (dim < 1) {
807                 log_text("Invalid array dimension requested");
808                 assert(0);
809         }
810
811     /* Assemble the array class name */
812     namelen = element->name->blength;
813     
814     if (element->name->text[0] == '[') {
815         /* the element is itself an array */
816         namebuf = DMNEW(char, namelen + dim);
817         memcpy(namebuf + dim, element->name->text, namelen);
818         namelen += dim;
819     }
820     else {
821         /* the element is a non-array class */
822         namebuf = DMNEW(char, namelen + 2 + dim);
823         namebuf[dim] = 'L';
824         memcpy(namebuf + dim + 1, element->name->text, namelen);
825         namelen += (2 + dim);
826         namebuf[namelen - 1] = ';';
827     }
828         memset(namebuf, '[', dim);
829
830         c = get_array_class(utf_new(namebuf, namelen),
831                                                 element->classloader,
832                                                 element->classloader,
833                                                 link);
834
835         dump_release(dumpsize);
836
837         return c;
838 }
839
840
841 /* class_lookup_classref *******************************************************
842
843    Looks up the constant_classref for a given classname in the classref
844    tables of a class.
845
846    IN:
847        cls..............the class containing the reference
848            name.............the name of the class refered to
849
850     RETURN VALUE:
851            a pointer to a constant_classref, or 
852            NULL if the reference was not found
853    
854 *******************************************************************************/
855
856 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
857 {
858         constant_classref *ref;
859         extra_classref *xref;
860         int count;
861
862         assert(cls);
863         assert(name);
864         assert(!cls->classrefcount || cls->classrefs);
865         
866         /* first search the main classref table */
867         count = cls->classrefcount;
868         ref = cls->classrefs;
869         for (; count; --count, ++ref)
870                 if (ref->name == name)
871                         return ref;
872
873         /* next try the list of extra classrefs */
874         for (xref = cls->extclassrefs; xref; xref = xref->next) {
875                 if (xref->classref.name == name)
876                         return &(xref->classref);
877         }
878
879         /* not found */
880         return NULL;
881 }
882
883
884 /* class_get_classref **********************************************************
885
886    Returns the constant_classref for a given classname.
887
888    IN:
889        cls..............the class containing the reference
890            name.............the name of the class refered to
891
892    RETURN VALUE:
893        a pointer to a constant_classref (never NULL)
894
895    NOTE:
896        The given name is not checked for validity!
897    
898 *******************************************************************************/
899
900 constant_classref *class_get_classref(classinfo *cls, utf *name)
901 {
902         constant_classref *ref;
903         extra_classref *xref;
904
905         assert(cls);
906         assert(name);
907
908         ref = class_lookup_classref(cls,name);
909         if (ref)
910                 return ref;
911
912         xref = NEW(extra_classref);
913         CLASSREF_INIT(xref->classref,cls,name);
914
915         xref->next = cls->extclassrefs;
916         cls->extclassrefs = xref;
917
918         return &(xref->classref);
919 }
920
921
922 /* class_get_self_classref *****************************************************
923
924    Returns the constant_classref to the class itself.
925
926    IN:
927        cls..............the class containing the reference
928
929    RETURN VALUE:
930        a pointer to a constant_classref (never NULL)
931
932 *******************************************************************************/
933
934 constant_classref *class_get_self_classref(classinfo *cls)
935 {
936         /* XXX this should be done in a faster way. Maybe always make */
937         /* the classref of index 0 a self reference.                  */
938         return class_get_classref(cls,cls->name);
939 }
940
941 /* class_get_classref_multiarray_of ********************************************
942
943    Returns an array type reference with the given dimension and element class
944    reference.
945
946    IN:
947        dim..............the requested dimension
948                             dim must be in [1;255]. This is NOT checked!
949            ref..............the component class reference
950
951    RETURN VALUE:
952        a pointer to the class reference for the array type
953
954    NOTE:
955        The referer of `ref` is used as the referer for the new classref.
956
957 *******************************************************************************/
958
959 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
960 {
961     s4 namelen;
962     char *namebuf;
963         s4 dumpsize;
964         constant_classref *cr;
965
966         assert(ref);
967         assert(dim >= 1 && dim <= 255);
968
969         dumpsize = dump_size();
970
971     /* Assemble the array class name */
972     namelen = ref->name->blength;
973     
974     if (ref->name->text[0] == '[') {
975         /* the element is itself an array */
976         namebuf = DMNEW(char, namelen + dim);
977         memcpy(namebuf + dim, ref->name->text, namelen);
978         namelen += dim;
979     }
980     else {
981         /* the element is a non-array class */
982         namebuf = DMNEW(char, namelen + 2 + dim);
983         namebuf[dim] = 'L';
984         memcpy(namebuf + dim + 1, ref->name->text, namelen);
985         namelen += (2 + dim);
986         namebuf[namelen - 1] = ';';
987     }
988         memset(namebuf, '[', dim);
989
990     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
991
992         dump_release(dumpsize);
993
994         return cr;
995 }
996
997
998 /* class_get_classref_component_of *********************************************
999
1000    Returns the component classref of a given array type reference
1001
1002    IN:
1003        ref..............the array type reference
1004
1005    RETURN VALUE:
1006        a reference to the component class, or
1007            NULL if `ref` is not an object array type reference
1008
1009    NOTE:
1010        The referer of `ref` is used as the referer for the new classref.
1011
1012 *******************************************************************************/
1013
1014 constant_classref *class_get_classref_component_of(constant_classref *ref)
1015 {
1016         s4 namelen;
1017         char *name;
1018         
1019         assert(ref);
1020
1021         name = ref->name->text;
1022         if (*name++ != '[')
1023                 return NULL;
1024         
1025         namelen = ref->name->blength - 1;
1026         if (*name == 'L') {
1027                 name++;
1028                 namelen -= 2;
1029         }
1030         else if (*name != '[') {
1031                 return NULL;
1032         }
1033
1034     return class_get_classref(ref->referer, utf_new(name, namelen));
1035 }
1036
1037
1038 /* class_findmethod ************************************************************
1039         
1040    Searches a 'classinfo' structure for a method having the given name
1041    and descriptor. If descriptor is NULL, it is ignored.
1042
1043 *******************************************************************************/
1044
1045 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1046 {
1047         methodinfo *m;
1048         s4          i;
1049
1050         for (i = 0; i < c->methodscount; i++) {
1051                 m = &(c->methods[i]);
1052
1053                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1054                         return m;
1055         }
1056
1057         return NULL;
1058 }
1059
1060
1061 /* class_resolvemethod *********************************************************
1062         
1063    Searches a class and it's super classes for a method.
1064
1065    Superinterfaces are *not* searched.
1066
1067 *******************************************************************************/
1068
1069 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1070 {
1071         methodinfo *m;
1072
1073         while (c) {
1074                 m = class_findmethod(c, name, desc);
1075
1076                 if (m)
1077                         return m;
1078
1079                 /* JVM Specification bug: 
1080
1081                    It is important NOT to resolve special <init> and <clinit>
1082                    methods to super classes or interfaces; yet, this is not
1083                    explicited in the specification.  Section 5.4.3.3 should be
1084                    updated appropriately.  */
1085
1086                 if (name == utf_init || name == utf_clinit)
1087                         return NULL;
1088
1089                 c = c->super.cls;
1090         }
1091
1092         return NULL;
1093 }
1094
1095
1096 /* class_resolveinterfacemethod_intern *****************************************
1097
1098    Internally used helper function. Do not use this directly.
1099
1100 *******************************************************************************/
1101
1102 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1103                                                                                                            utf *name, utf *desc)
1104 {
1105         methodinfo *m;
1106         s4          i;
1107
1108         /* try to find the method in the class */
1109
1110         m = class_findmethod(c, name, desc);
1111
1112         if (m != NULL)
1113                 return m;
1114
1115         /* no method found? try the superinterfaces */
1116
1117         for (i = 0; i < c->interfacescount; i++) {
1118                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1119                                                                                                         name, desc);
1120
1121                 if (m != NULL)
1122                         return m;
1123         }
1124
1125         /* no method found */
1126
1127         return NULL;
1128 }
1129
1130
1131 /* class_resolveclassmethod ****************************************************
1132         
1133    Resolves a reference from REFERER to a method with NAME and DESC in
1134    class C.
1135
1136    If the method cannot be resolved the return value is NULL. If
1137    EXCEPT is true *exceptionptr is set, too.
1138
1139 *******************************************************************************/
1140
1141 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1142                                                                          classinfo *referer, bool throwexception)
1143 {
1144         classinfo  *cls;
1145         methodinfo *m;
1146         s4          i;
1147
1148 /*      if (c->flags & ACC_INTERFACE) { */
1149 /*              if (throwexception) */
1150 /*                      *exceptionptr = */
1151 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1152 /*              return NULL; */
1153 /*      } */
1154
1155         /* try class c and its superclasses */
1156
1157         cls = c;
1158
1159         m = class_resolvemethod(cls, name, desc);
1160
1161         if (m != NULL)
1162                 goto found;
1163
1164         /* try the superinterfaces */
1165
1166         for (i = 0; i < c->interfacescount; i++) {
1167                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1168                                                                                                 name, desc);
1169
1170                 if (m != NULL)
1171                         goto found;
1172         }
1173         
1174         if (throwexception)
1175                 exceptions_throw_nosuchmethoderror(c, name, desc);
1176
1177         return NULL;
1178
1179  found:
1180         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1181                 if (throwexception)
1182                         exceptions_throw_abstractmethoderror();
1183
1184                 return NULL;
1185         }
1186
1187         /* XXX check access rights */
1188
1189         return m;
1190 }
1191
1192
1193 /* class_resolveinterfacemethod ************************************************
1194
1195    Resolves a reference from REFERER to a method with NAME and DESC in
1196    interface C.
1197
1198    If the method cannot be resolved the return value is NULL. If
1199    EXCEPT is true *exceptionptr is set, too.
1200
1201 *******************************************************************************/
1202
1203 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1204                                                                                  classinfo *referer, bool throwexception)
1205 {
1206         methodinfo *mi;
1207
1208         if (!(c->flags & ACC_INTERFACE)) {
1209                 if (throwexception)
1210                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1211
1212                 return NULL;
1213         }
1214
1215         mi = class_resolveinterfacemethod_intern(c, name, desc);
1216
1217         if (mi != NULL)
1218                 return mi;
1219
1220         /* try class java.lang.Object */
1221
1222         mi = class_findmethod(class_java_lang_Object, name, desc);
1223
1224         if (mi != NULL)
1225                 return mi;
1226
1227         if (throwexception)
1228                 exceptions_throw_nosuchmethoderror(c, name, desc);
1229
1230         return NULL;
1231 }
1232
1233
1234 /* class_findfield *************************************************************
1235         
1236    Searches for field with specified name and type in a classinfo
1237    structure. If no such field is found NULL is returned.
1238
1239 *******************************************************************************/
1240
1241 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1242 {
1243         s4 i;
1244
1245         for (i = 0; i < c->fieldscount; i++)
1246                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1247                         return &(c->fields[i]);
1248
1249         if (c->super.cls)
1250                 return class_findfield(c->super.cls, name, desc);
1251
1252         return NULL;
1253 }
1254
1255
1256 /* class_findfield_approx ******************************************************
1257         
1258    Searches in 'classinfo'-structure for a field with the specified
1259    name.
1260
1261 *******************************************************************************/
1262  
1263 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1264 {
1265         s4 i;
1266
1267         /* get field index */
1268
1269         i = class_findfield_index_by_name(c, name);
1270
1271         /* field was not found, return */
1272
1273         if (i == -1)
1274                 return NULL;
1275
1276         /* return field address */
1277
1278         return &(c->fields[i]);
1279 }
1280
1281
1282 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1283 {
1284         s4 i;
1285
1286         for (i = 0; i < c->fieldscount; i++) {
1287                 /* compare field names */
1288
1289                 if ((c->fields[i].name == name))
1290                         return i;
1291         }
1292
1293         /* field was not found, raise exception */      
1294
1295         exceptions_throw_nosuchfielderror(c, name);
1296
1297         return -1;
1298 }
1299
1300
1301 /****************** Function: class_resolvefield_int ***************************
1302
1303     This is an internally used helper function. Do not use this directly.
1304
1305         Tries to resolve a field having the given name and type.
1306     If the field cannot be resolved, NULL is returned.
1307
1308 *******************************************************************************/
1309
1310 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1311 {
1312         fieldinfo *fi;
1313         s4         i;
1314
1315         /* search for field in class c */
1316
1317         for (i = 0; i < c->fieldscount; i++) { 
1318                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1319                         return &(c->fields[i]);
1320                 }
1321     }
1322
1323         /* try superinterfaces recursively */
1324
1325         for (i = 0; i < c->interfacescount; i++) {
1326                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1327                 if (fi)
1328                         return fi;
1329         }
1330
1331         /* try superclass */
1332
1333         if (c->super.cls)
1334                 return class_resolvefield_int(c->super.cls, name, desc);
1335
1336         /* not found */
1337
1338         return NULL;
1339 }
1340
1341
1342 /********************* Function: class_resolvefield ***************************
1343         
1344         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1345
1346     If the field cannot be resolved the return value is NULL. If EXCEPT is
1347     true *exceptionptr is set, too.
1348
1349 *******************************************************************************/
1350
1351 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1352                                                           classinfo *referer, bool throwexception)
1353 {
1354         fieldinfo *fi;
1355
1356         fi = class_resolvefield_int(c, name, desc);
1357
1358         if (!fi) {
1359                 if (throwexception)
1360                         exceptions_throw_nosuchfielderror(c, name);
1361
1362                 return NULL;
1363         }
1364
1365         /* XXX check access rights */
1366
1367         return fi;
1368 }
1369
1370
1371 /* class_issubclass ************************************************************
1372
1373    Checks if sub is a descendant of super.
1374         
1375 *******************************************************************************/
1376
1377 bool class_issubclass(classinfo *sub, classinfo *super)
1378 {
1379         for (;;) {
1380                 if (!sub)
1381                         return false;
1382
1383                 if (sub == super)
1384                         return true;
1385
1386                 sub = sub->super.cls;
1387         }
1388 }
1389
1390
1391 /* class_isanysubclass *********************************************************
1392
1393    Checks a subclass relation between two classes. Implemented
1394    interfaces are interpreted as super classes.
1395
1396    Return value: 1 ... sub is subclass of super
1397                  0 ... otherwise
1398
1399 *******************************************************************************/
1400
1401 bool class_isanysubclass(classinfo *sub, classinfo *super)
1402 {
1403         castinfo classvalues;
1404         u4       diffval;
1405         bool     result;
1406
1407         /* This is the trivial case. */
1408
1409         if (sub == super)
1410                 return true;
1411
1412         /* Primitive classes are only subclasses of themselves. */
1413
1414         if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
1415                 (super->flags & ACC_CLASS_PRIMITIVE))
1416                 return false;
1417
1418         /* Check for interfaces. */
1419
1420         if (super->flags & ACC_INTERFACE) {
1421                 result = (sub->vftbl->interfacetablelength > super->index) &&
1422                         (sub->vftbl->interfacetable[-super->index] != NULL);
1423         }
1424         else {
1425                 /* java.lang.Object is the only super class of any
1426                    interface. */
1427
1428                 if (sub->flags & ACC_INTERFACE)
1429                         return (super == class_java_lang_Object);
1430
1431                 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1432
1433                 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1434                 result  = diffval <= (u4) classvalues.super_diffval;
1435         }
1436
1437         return result;
1438 }
1439
1440
1441 /* class_printflags ************************************************************
1442
1443    Prints flags of a class.
1444
1445 *******************************************************************************/
1446
1447 #if !defined(NDEBUG)
1448 void class_printflags(classinfo *c)
1449 {
1450         if (c == NULL) {
1451                 printf("NULL");
1452                 return;
1453         }
1454
1455         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1456         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1457         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1458         if (c->flags & ACC_STATIC)       printf(" STATIC");
1459         if (c->flags & ACC_FINAL)        printf(" FINAL");
1460         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1461         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1462         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1463         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1464         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1465         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1466 }
1467 #endif
1468
1469
1470 /* class_print *****************************************************************
1471
1472    Prints classname plus flags.
1473
1474 *******************************************************************************/
1475
1476 #if !defined(NDEBUG)
1477 void class_print(classinfo *c)
1478 {
1479         if (c == NULL) {
1480                 printf("NULL");
1481                 return;
1482         }
1483
1484         utf_display_printable_ascii(c->name);
1485         class_printflags(c);
1486 }
1487 #endif
1488
1489
1490 /* class_classref_print ********************************************************
1491
1492    Prints classname plus referer class.
1493
1494 *******************************************************************************/
1495
1496 #if !defined(NDEBUG)
1497 void class_classref_print(constant_classref *cr)
1498 {
1499         if (cr == NULL) {
1500                 printf("NULL");
1501                 return;
1502         }
1503
1504         utf_display_printable_ascii(cr->name);
1505         printf("(ref.by ");
1506         if (cr->referer)
1507                 class_print(cr->referer);
1508         else
1509                 printf("NULL");
1510         printf(")");
1511 }
1512 #endif
1513
1514
1515 /* class_println ***************************************************************
1516
1517    Prints classname plus flags and new line.
1518
1519 *******************************************************************************/
1520
1521 #if !defined(NDEBUG)
1522 void class_println(classinfo *c)
1523 {
1524         class_print(c);
1525         printf("\n");
1526 }
1527 #endif
1528
1529
1530 /* class_classref_println ******************************************************
1531
1532    Prints classname plus referer class and new line.
1533
1534 *******************************************************************************/
1535
1536 #if !defined(NDEBUG)
1537 void class_classref_println(constant_classref *cr)
1538 {
1539         class_classref_print(cr);
1540         printf("\n");
1541 }
1542 #endif
1543
1544
1545 /* class_classref_or_classinfo_print *******************************************
1546
1547    Prints classname plus referer class.
1548
1549 *******************************************************************************/
1550
1551 #if !defined(NDEBUG)
1552 void class_classref_or_classinfo_print(classref_or_classinfo c)
1553 {
1554         if (c.any == NULL) {
1555                 printf("(classref_or_classinfo) NULL");
1556                 return;
1557         }
1558         if (IS_CLASSREF(c))
1559                 class_classref_print(c.ref);
1560         else
1561                 class_print(c.cls);
1562 }
1563 #endif
1564
1565
1566 /* class_classref_or_classinfo_println *****************************************
1567
1568    Prints classname plus referer class and a newline.
1569
1570 *******************************************************************************/
1571
1572 void class_classref_or_classinfo_println(classref_or_classinfo c)
1573 {
1574         class_classref_or_classinfo_println(c);
1575         printf("\n");
1576 }
1577
1578
1579 /* class_showconstantpool ******************************************************
1580
1581    Dump the constant pool of the given class to stdout.
1582
1583 *******************************************************************************/
1584
1585 #if !defined(NDEBUG)
1586 void class_showconstantpool (classinfo *c) 
1587 {
1588         u4 i;
1589         voidptr e;
1590
1591         printf ("---- dump of constant pool ----\n");
1592
1593         for (i=0; i<c->cpcount; i++) {
1594                 printf ("#%d:  ", (int) i);
1595                 
1596                 e = c -> cpinfos [i];
1597                 if (e) {
1598                         
1599                         switch (c -> cptags [i]) {
1600                         case CONSTANT_Class:
1601                                 printf ("Classreference -> ");
1602                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1603                                 break;
1604                         case CONSTANT_Fieldref:
1605                                 printf ("Fieldref -> ");
1606                                 field_fieldref_print((constant_FMIref *) e);
1607                                 break;
1608                         case CONSTANT_Methodref:
1609                                 printf ("Methodref -> ");
1610                                 method_methodref_print((constant_FMIref *) e);
1611                                 break;
1612                         case CONSTANT_InterfaceMethodref:
1613                                 printf ("InterfaceMethod -> ");
1614                                 method_methodref_print((constant_FMIref *) e);
1615                                 break;
1616                         case CONSTANT_String:
1617                                 printf ("String -> ");
1618                                 utf_display_printable_ascii (e);
1619                                 break;
1620                         case CONSTANT_Integer:
1621                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1622                                 break;
1623                         case CONSTANT_Float:
1624                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1625                                 break;
1626                         case CONSTANT_Double:
1627                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1628                                 break;
1629                         case CONSTANT_Long:
1630                                 {
1631                                         u8 v = ((constant_long*)e) -> value;
1632 #if U8_AVAILABLE
1633                                         printf ("Long -> %ld", (long int) v);
1634 #else
1635                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1636                                                         (long int) v.high, (long int) v.low);
1637 #endif 
1638                                 }
1639                                 break;
1640                         case CONSTANT_NameAndType:
1641                                 {
1642                                         constant_nameandtype *cnt = e;
1643                                         printf ("NameAndType: ");
1644                                         utf_display_printable_ascii (cnt->name);
1645                                         printf (" ");
1646                                         utf_display_printable_ascii (cnt->descriptor);
1647                                 }
1648                                 break;
1649                         case CONSTANT_Utf8:
1650                                 printf ("Utf8 -> ");
1651                                 utf_display_printable_ascii (e);
1652                                 break;
1653                         default: 
1654                                 log_text("Invalid type of ConstantPool-Entry");
1655                                 assert(0);
1656                         }
1657                 }
1658
1659                 printf ("\n");
1660         }
1661 }
1662 #endif /* !defined(NDEBUG) */
1663
1664
1665 /* class_showmethods ***********************************************************
1666
1667    Dump info about the fields and methods of the given class to stdout.
1668
1669 *******************************************************************************/
1670
1671 #if !defined(NDEBUG)
1672 void class_showmethods (classinfo *c)
1673 {
1674         s4 i;
1675         
1676         printf("--------- Fields and Methods ----------------\n");
1677         printf("Flags: ");
1678         class_printflags(c);
1679         printf("\n");
1680
1681         printf("This: ");
1682         utf_display_printable_ascii(c->name);
1683         printf("\n");
1684
1685         if (c->super.cls) {
1686                 printf("Super: ");
1687                 utf_display_printable_ascii(c->super.cls->name);
1688                 printf ("\n");
1689         }
1690
1691         printf("Index: %d\n", c->index);
1692         
1693         printf("Interfaces:\n");        
1694         for (i = 0; i < c->interfacescount; i++) {
1695                 printf("   ");
1696                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1697                 printf (" (%d)\n", c->interfaces[i].cls->index);
1698         }
1699
1700         printf("Fields:\n");
1701         for (i = 0; i < c->fieldscount; i++)
1702                 field_println(&(c->fields[i]));
1703
1704         printf("Methods:\n");
1705         for (i = 0; i < c->methodscount; i++) {
1706                 methodinfo *m = &(c->methods[i]);
1707
1708                 if (!(m->flags & ACC_STATIC))
1709                         printf("vftblindex: %d   ", m->vftblindex);
1710
1711                 method_println(m);
1712         }
1713
1714         printf ("Virtual function table:\n");
1715         for (i = 0; i < c->vftbl->vftbllength; i++)
1716                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1717 }
1718 #endif /* !defined(NDEBUG) */
1719
1720
1721 /*
1722  * These are local overrides for various environment variables in Emacs.
1723  * Please do not remove this and leave it at the end of the file, where
1724  * Emacs will automagically detect them.
1725  * ---------------------------------------------------------------------
1726  * Local variables:
1727  * mode: c
1728  * indent-tabs-mode: t
1729  * c-basic-offset: 4
1730  * tab-width: 4
1731  * End:
1732  * vim:noexpandtab:sw=4:ts=4:
1733  */