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