d3ebee78b3e26c74bfad977b08ec3d7b35e03cfb
[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 8249 2007-07-31 12:59:03Z panzi $
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 #include "vm/resolve.h"
50
51 #include "vm/jit/asmpart.h"
52
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/loader.h"
56 #include "vmcore/options.h"
57
58 #if defined(ENABLE_STATISTICS)
59 # include "vmcore/statistics.h"
60 #endif
61
62 #include "vmcore/suck.h"
63 #include "vmcore/utf8.h"
64
65
66 /* global variables ***********************************************************/
67
68 /* frequently used classes ****************************************************/
69
70 /* important system classes */
71
72 classinfo *class_java_lang_Object;
73 classinfo *class_java_lang_Class;
74 classinfo *class_java_lang_ClassLoader;
75 classinfo *class_java_lang_Cloneable;
76 classinfo *class_java_lang_SecurityManager;
77 classinfo *class_java_lang_String;
78 classinfo *class_java_lang_System;
79 classinfo *class_java_lang_Thread;
80 classinfo *class_java_lang_ThreadGroup;
81 classinfo *class_java_lang_VMSystem;
82 classinfo *class_java_lang_VMThread;
83 classinfo *class_java_io_Serializable;
84
85 #if defined(WITH_CLASSPATH_SUN)
86 classinfo *class_sun_reflect_MagicAccessorImpl;
87 #endif
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
136 #if defined(ENABLE_ANNOTATIONS)
137 classinfo *class_sun_reflect_ConstantPool;
138 classinfo *class_sun_reflect_annotation_AnnotationParser;
139 #endif
140 #endif
141
142
143 /* pseudo classes for the typechecker */
144
145 classinfo *pseudo_class_Arraystub;
146 classinfo *pseudo_class_Null;
147 classinfo *pseudo_class_New;
148
149
150 /* class_set_packagename *******************************************************
151
152    Derive the package name from the class name and store it in the struct.
153
154 *******************************************************************************/
155
156 void class_set_packagename(classinfo *c)
157 {
158         char *p = UTF_END(c->name) - 1;
159         char *start = c->name->text;
160
161         /* set the package name */
162         /* classes in the unnamed package keep packagename == NULL */
163
164         if (c->name->text[0] == '[') {
165                 /* set packagename of arrays to the element's package */
166
167                 for (; *start == '['; start++);
168
169                 /* skip the 'L' in arrays of references */
170                 if (*start == 'L')
171                         start++;
172
173                 for (; (p > start) && (*p != '/'); --p);
174
175                 c->packagename = utf_new(start, p - start);
176
177         } else {
178                 for (; (p > start) && (*p != '/'); --p);
179
180                 c->packagename = utf_new(start, p - start);
181         }
182 }
183
184
185 /* class_create_classinfo ******************************************************
186
187    Create a new classinfo struct. The class name is set to the given utf *,
188    most other fields are initialized to zero.
189
190    Note: classname may be NULL. In this case a not-yet-named classinfo is
191          created. The name must be filled in later and class_set_packagename
192                  must be called after that.
193
194 *******************************************************************************/
195
196 classinfo *class_create_classinfo(utf *classname)
197 {
198         classinfo *c;
199
200 #if defined(ENABLE_STATISTICS)
201         if (opt_stat)
202                 size_classinfo += sizeof(classinfo);
203 #endif
204
205         /* we use a safe name for temporarily unnamed classes */
206
207         if (classname == NULL)
208                 classname = utf_not_named_yet;
209
210 #if !defined(NDEBUG)
211         if (initverbose)
212                 log_message_utf("Creating class: ", classname);
213 #endif
214
215         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
216
217         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
218         /*c=NEW(classinfo);*/
219         c->name = classname;
220
221         /* Set the header.vftbl of all loaded classes to the one of
222        java.lang.Class, so Java code can use a class as object. */
223
224         if (class_java_lang_Class != NULL)
225                 if (class_java_lang_Class->vftbl != NULL)
226                         c->object.header.vftbl = class_java_lang_Class->vftbl;
227
228 #if defined(ENABLE_JAVASE)
229         /* check if the class is a reference class and flag it */
230
231         if (classname == utf_java_lang_ref_SoftReference) {
232                 c->flags |= ACC_CLASS_REFERENCE_SOFT;
233         }
234         else if (classname == utf_java_lang_ref_WeakReference) {
235                 c->flags |= ACC_CLASS_REFERENCE_WEAK;
236         }
237         else if (classname == utf_java_lang_ref_PhantomReference) {
238                 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
239         }
240 #endif
241
242         if (classname != utf_not_named_yet)
243                 class_set_packagename(c);
244
245         LOCK_INIT_OBJECT_LOCK(&c->object.header);
246
247         return c;
248 }
249
250
251 /* class_postset_header_vftbl **************************************************
252
253    Set the header.vftbl of all classes created before java.lang.Class
254    was linked.  This is necessary that Java code can use a class as
255    object.
256
257 *******************************************************************************/
258
259 void class_postset_header_vftbl(void)
260 {
261         classinfo *c;
262         u4 slot;
263         classcache_name_entry *nmen;
264         classcache_class_entry *clsen;
265
266         assert(class_java_lang_Class);
267
268         for (slot = 0; slot < hashtable_classcache.size; slot++) {
269                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
270
271                 for (; nmen; nmen = nmen->hashlink) {
272                         /* iterate over all class entries */
273
274                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
275                                 c = clsen->classobj;
276
277                                 /* now set the the vftbl */
278
279                                 if (c->object.header.vftbl == NULL)
280                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
281                         }
282                 }
283         }
284 }
285
286 /* class_define ****************************************************************
287
288    Calls the loader and defines a class in the VM.
289
290 *******************************************************************************/
291
292 classinfo *class_define(utf *name, java_objectheader *cl, int32_t length, const uint8_t *data)
293 {
294         classinfo   *c;
295         classinfo   *r;
296         classbuffer *cb;
297
298         if (name != NULL) {
299                 /* check if this class has already been defined */
300
301                 c = classcache_lookup_defined_or_initiated(cl, name);
302
303                 if (c != NULL) {
304                         exceptions_throw_linkageerror("duplicate class definition: ", c);
305                         return NULL;
306                 }
307         } 
308
309         /* create a new classinfo struct */
310
311         c = class_create_classinfo(name);
312
313 #if defined(ENABLE_STATISTICS)
314         /* measure time */
315
316         if (opt_getloadingtime)
317                 loadingtime_start();
318 #endif
319
320         /* build a classbuffer with the given data */
321
322         cb = NEW(classbuffer);
323
324         cb->class = c;
325         cb->size  = length;
326         cb->data  = data;
327         cb->pos   = cb->data;
328
329         /* preset the defining classloader */
330
331         c->classloader = cl;
332
333         /* load the class from this buffer */
334
335         r = load_class_from_classbuffer(cb);
336
337         /* free memory */
338
339         FREE(cb, classbuffer);
340
341 #if defined(ENABLE_STATISTICS)
342         /* measure time */
343
344         if (opt_getloadingtime)
345                 loadingtime_stop();
346 #endif
347
348         if (r == NULL) {
349                 /* If return value is NULL, we had a problem and the class is
350                    not loaded.  Now free the allocated memory, otherwise we
351                    could run into a DOS. */
352
353                 class_free(c);
354
355                 return NULL;
356         }
357
358         /* Store the newly defined class in the class cache. This call
359            also checks whether a class of the same name has already been
360            defined by the same defining loader, and if so, replaces the
361            newly created class by the one defined earlier. */
362
363         /* Important: The classinfo given to classcache_store must be
364                       fully prepared because another thread may return
365                       this pointer after the lookup at to top of this
366                       function directly after the class cache lock has
367                       been released. */
368
369         c = classcache_store(cl, c, true);
370
371         return c;
372 }
373
374
375 /* class_load_attribute_sourcefile *********************************************
376
377    SourceFile_attribute {
378        u2 attribute_name_index;
379        u4 attribute_length;
380            u2 sourcefile_index;
381    }
382
383 *******************************************************************************/
384
385 static bool class_load_attribute_sourcefile(classbuffer *cb)
386 {
387         classinfo *c;
388         u4         attribute_length;
389         u2         sourcefile_index;
390         utf       *sourcefile;
391
392         /* get classinfo */
393
394         c = cb->class;
395
396         /* check buffer size */
397
398         if (!suck_check_classbuffer_size(cb, 4 + 2))
399                 return false;
400
401         /* check attribute length */
402
403         attribute_length = suck_u4(cb);
404
405         if (attribute_length != 2) {
406                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
407                 return false;
408         }
409
410         /* there can be no more than one SourceFile attribute */
411
412         if (c->sourcefile != NULL) {
413                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
414                 return false;
415         }
416
417         /* get sourcefile */
418
419         sourcefile_index = suck_u2(cb);
420         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
421
422         if (sourcefile == NULL)
423                 return false;
424
425         /* store sourcefile */
426
427         c->sourcefile = sourcefile;
428
429         return true;
430 }
431
432
433 /* class_load_attribute_enclosingmethod ****************************************
434
435    EnclosingMethod_attribute {
436        u2 attribute_name_index;
437        u4 attribute_length;
438            u2 class_index;
439            u2 method_index;
440    }
441
442 *******************************************************************************/
443
444 #if defined(ENABLE_JAVASE)
445 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
446 {
447         classinfo             *c;
448         u4                     attribute_length;
449         u2                     class_index;
450         u2                     method_index;
451         classref_or_classinfo  cr;
452         constant_nameandtype  *cn;
453
454         /* get classinfo */
455
456         c = cb->class;
457
458         /* check buffer size */
459
460         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
461                 return false;
462
463         /* check attribute length */
464
465         attribute_length = suck_u4(cb);
466
467         if (attribute_length != 4) {
468                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
469                 return false;
470         }
471
472         /* there can be no more than one EnclosingMethod attribute */
473
474         if (c->enclosingmethod != NULL) {
475                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
476                 return false;
477         }
478
479         /* get class index */
480
481         class_index = suck_u2(cb);
482         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
483
484         /* get method index */
485
486         method_index = suck_u2(cb);
487         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
488
489         /* store info in classinfo */
490
491         c->enclosingclass.any = cr.any;
492         c->enclosingmethod    = cn;
493
494         return true;
495 }
496 #endif /* defined(ENABLE_JAVASE) */
497
498
499 /* class_load_attributes *******************************************************
500
501    Read attributes from ClassFile.
502
503    attribute_info {
504        u2 attribute_name_index;
505        u4 attribute_length;
506        u1 info[attribute_length];
507    }
508
509    InnerClasses_attribute {
510        u2 attribute_name_index;
511        u4 attribute_length;
512    }
513
514 *******************************************************************************/
515
516 bool class_load_attributes(classbuffer *cb)
517 {
518         classinfo *c;
519         u4         i, j;
520         u2         attributes_count;
521         u2         attribute_name_index;
522         utf       *attribute_name;
523
524         c = cb->class;
525
526         /* get attributes count */
527
528         if (!suck_check_classbuffer_size(cb, 2))
529                 return false;
530
531         attributes_count = suck_u2(cb);
532
533         for (i = 0; i < attributes_count; i++) {
534                 /* get attribute name */
535
536                 if (!suck_check_classbuffer_size(cb, 2))
537                         return false;
538
539                 attribute_name_index = suck_u2(cb);
540                 attribute_name =
541                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
542
543                 if (attribute_name == NULL)
544                         return false;
545
546                 if (attribute_name == utf_InnerClasses) {
547                         /* InnerClasses */
548
549                         if (c->innerclass != NULL) {
550                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
551                                 return false;
552                         }
553                                 
554                         if (!suck_check_classbuffer_size(cb, 4 + 2))
555                                 return false;
556
557                         /* skip attribute length */
558                         suck_u4(cb);
559
560                         /* number of records */
561                         c->innerclasscount = suck_u2(cb);
562
563                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
564                                 return false;
565
566                         /* allocate memory for innerclass structure */
567                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
568
569                         for (j = 0; j < c->innerclasscount; j++) {
570                                 /* The innerclass structure contains a class with an encoded
571                                    name, its defining scope, its simple name and a bitmask of
572                                    the access flags. If an inner class is not a member, its
573                                    outer_class is NULL, if a class is anonymous, its name is
574                                    NULL. */
575                                                                 
576                                 innerclassinfo *info = c->innerclass + j;
577
578                                 info->inner_class.ref =
579                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
580                                 info->outer_class.ref =
581                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
582                                 info->name =
583                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
584                                 info->flags = suck_u2(cb);
585                         }
586                 }
587                 else if (attribute_name == utf_SourceFile) {
588                         /* SourceFile */
589
590                         if (!class_load_attribute_sourcefile(cb))
591                                 return false;
592                 }
593 #if defined(ENABLE_JAVASE)
594                 else if (attribute_name == utf_EnclosingMethod) {
595                         /* EnclosingMethod */
596
597                         if (!class_load_attribute_enclosingmethod(cb))
598                                 return false;
599                 }
600                 else if (attribute_name == utf_Signature) {
601                         /* Signature */
602
603                         if (!loader_load_attribute_signature(cb, &(c->signature)))
604                                 return false;
605                 }
606 #endif
607
608 #if defined(ENABLE_ANNOTATIONS)
609                 /* XXX We can't do a release with that enabled */
610
611                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
612                         /* RuntimeVisibleAnnotations */
613                         if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
614                                 return false;
615                 }
616                 /* XXX RuntimeInvisibleAnnotations should only be loaded
617                  * (or returned to Java) if some commandline options says so.
618                  * Currently there is no such option available in cacao,
619                  * therefore I load them allways (for testing purpose).
620                  * Anyway, bytecode for RuntimeInvisibleAnnotations is only
621                  * generated if you tell javac to do so. So in most cases
622                  * there won't be any.
623                  */
624                 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
625                         /* RuntimeInvisibleAnnotations */
626                         if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
627                                 return false;
628                 }
629 #endif
630
631                 else {
632                         /* unknown attribute */
633
634                         if (!loader_skip_attribute_body(cb))
635                                 return false;
636                 }
637         }
638
639         return true;
640 }
641
642
643 /* class_freepool **************************************************************
644
645         Frees all resources used by this classes Constant Pool.
646
647 *******************************************************************************/
648
649 static void class_freecpool(classinfo *c)
650 {
651         u4 idx;
652         u4 tag;
653         voidptr info;
654         
655         if (c->cptags && c->cpinfos) {
656                 for (idx = 0; idx < c->cpcount; idx++) {
657                         tag = c->cptags[idx];
658                         info = c->cpinfos[idx];
659                 
660                         if (info != NULL) {
661                                 switch (tag) {
662                                 case CONSTANT_Fieldref:
663                                 case CONSTANT_Methodref:
664                                 case CONSTANT_InterfaceMethodref:
665                                         FREE(info, constant_FMIref);
666                                         break;
667                                 case CONSTANT_Integer:
668                                         FREE(info, constant_integer);
669                                         break;
670                                 case CONSTANT_Float:
671                                         FREE(info, constant_float);
672                                         break;
673                                 case CONSTANT_Long:
674                                         FREE(info, constant_long);
675                                         break;
676                                 case CONSTANT_Double:
677                                         FREE(info, constant_double);
678                                         break;
679                                 case CONSTANT_NameAndType:
680                                         FREE(info, constant_nameandtype);
681                                         break;
682                                 }
683                         }
684                 }
685         }
686
687         if (c->cptags)
688                 MFREE(c->cptags, u1, c->cpcount);
689
690         if (c->cpinfos)
691                 MFREE(c->cpinfos, voidptr, c->cpcount);
692 }
693
694
695 /* class_getconstant ***********************************************************
696
697    Retrieves the value at position 'pos' of the constantpool of a
698    class. If the type of the value is other than 'ctype', an error is
699    thrown.
700
701 *******************************************************************************/
702
703 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
704 {
705         /* check index and type of constantpool entry */
706         /* (pos == 0 is caught by type comparison) */
707
708         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
709                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
710                 return NULL;
711         }
712
713         return c->cpinfos[pos];
714 }
715
716
717 /* innerclass_getconstant ******************************************************
718
719    Like class_getconstant, but if cptags is ZERO, null is returned.
720         
721 *******************************************************************************/
722
723 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
724 {
725         /* invalid position in constantpool */
726
727         if (pos >= c->cpcount) {
728                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
729                 return NULL;
730         }
731
732         /* constantpool entry of type 0 */      
733
734         if (c->cptags[pos] == 0)
735                 return NULL;
736
737         /* check type of constantpool entry */
738
739         if (c->cptags[pos] != ctype) {
740                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
741                 return NULL;
742         }
743                 
744         return c->cpinfos[pos];
745 }
746
747
748 /* class_free ******************************************************************
749
750    Frees all resources used by the class.
751
752 *******************************************************************************/
753
754 void class_free(classinfo *c)
755 {
756         s4 i;
757         vftbl_t *v;
758                 
759         class_freecpool(c);
760
761         if (c->interfaces)
762                 MFREE(c->interfaces, classinfo*, c->interfacescount);
763
764         if (c->fields) {
765                 for (i = 0; i < c->fieldscount; i++)
766                         field_free(&(c->fields[i]));
767 #if defined(ENABLE_CACAO_GC)
768                 MFREE(c->fields, fieldinfo, c->fieldscount);
769 #endif
770         }
771         
772         if (c->methods) {
773                 for (i = 0; i < c->methodscount; i++)
774                         method_free(&(c->methods[i]));
775                 MFREE(c->methods, methodinfo, c->methodscount);
776         }
777
778         if ((v = c->vftbl) != NULL) {
779                 if (v->arraydesc)
780                         mem_free(v->arraydesc,sizeof(arraydescriptor));
781                 
782                 for (i = 0; i < v->interfacetablelength; i++) {
783                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
784                 }
785                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
786
787                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
788                     sizeof(methodptr*) * (v->interfacetablelength -
789                                          (v->interfacetablelength > 0));
790                 v = (vftbl_t*) (((methodptr*) v) -
791                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
792                 mem_free(v, i);
793         }
794
795         if (c->innerclass)
796                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
797
798         /*      if (c->classvftbl)
799                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
800         
801 /*      GCFREE(c); */
802
803 #if defined(ENABLE_ANNOTATIONS)
804         annotation_bytearray_free(c->annotations);
805
806         annotation_bytearrays_free(c->method_annotations);
807         annotation_bytearrays_free(c->method_parameterannotations);
808         annotation_bytearrays_free(c->method_annotationdefaults);
809
810         annotation_bytearrays_free(c->field_annotations);
811 #endif
812 }
813
814
815 /* get_array_class *************************************************************
816
817    Returns the array class with the given name for the given
818    classloader, or NULL if an exception occurred.
819
820    Note: This function does eager loading. 
821
822 *******************************************************************************/
823
824 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
825                                                                                         java_objectheader *defloader,bool link)
826 {
827         classinfo *c;
828         
829         /* lookup this class in the classcache */
830         c = classcache_lookup(initloader,name);
831         if (!c)
832                 c = classcache_lookup_defined(defloader,name);
833
834         if (!c) {
835                 /* we have to create it */
836                 c = class_create_classinfo(name);
837                 c = load_newly_created_array(c,initloader);
838                 if (c == NULL)
839                         return NULL;
840         }
841
842         assert(c);
843         assert(c->state & CLASS_LOADED);
844         assert(c->classloader == defloader);
845
846         if (link && !(c->state & CLASS_LINKED))
847                 if (!link_class(c))
848                         return NULL;
849
850         assert(!link || (c->state & CLASS_LINKED));
851
852         return c;
853 }
854
855
856 /* class_array_of **************************************************************
857
858    Returns an array class with the given component class. The array
859    class is dynamically created if neccessary.
860
861 *******************************************************************************/
862
863 classinfo *class_array_of(classinfo *component, bool link)
864 {
865         java_objectheader *cl;
866     s4                 namelen;
867     char              *namebuf;
868         utf               *u;
869         classinfo         *c;
870         s4                 dumpsize;
871
872         cl = component->classloader;
873
874         dumpsize = dump_size();
875
876     /* Assemble the array class name */
877     namelen = component->name->blength;
878     
879     if (component->name->text[0] == '[') {
880         /* the component is itself an array */
881         namebuf = DMNEW(char, namelen + 1);
882         namebuf[0] = '[';
883         MCOPY(namebuf + 1, component->name->text, char, namelen);
884         namelen++;
885     }
886         else {
887         /* the component is a non-array class */
888         namebuf = DMNEW(char, namelen + 3);
889         namebuf[0] = '[';
890         namebuf[1] = 'L';
891         MCOPY(namebuf + 2, component->name->text, char, namelen);
892         namebuf[2 + namelen] = ';';
893         namelen += 3;
894     }
895
896         u = utf_new(namebuf, namelen);
897
898         c = get_array_class(u, cl, cl, link);
899
900         dump_release(dumpsize);
901
902         return c;
903 }
904
905
906 /* class_multiarray_of *********************************************************
907
908    Returns an array class with the given dimension and element class.
909    The array class is dynamically created if neccessary.
910
911 *******************************************************************************/
912
913 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
914 {
915     s4 namelen;
916     char *namebuf;
917         s4 dumpsize;
918         classinfo *c;
919
920         dumpsize = dump_size();
921
922         if (dim < 1) {
923                 log_text("Invalid array dimension requested");
924                 assert(0);
925         }
926
927     /* Assemble the array class name */
928     namelen = element->name->blength;
929     
930     if (element->name->text[0] == '[') {
931         /* the element is itself an array */
932         namebuf = DMNEW(char, namelen + dim);
933         memcpy(namebuf + dim, element->name->text, namelen);
934         namelen += dim;
935     }
936     else {
937         /* the element is a non-array class */
938         namebuf = DMNEW(char, namelen + 2 + dim);
939         namebuf[dim] = 'L';
940         memcpy(namebuf + dim + 1, element->name->text, namelen);
941         namelen += (2 + dim);
942         namebuf[namelen - 1] = ';';
943     }
944         memset(namebuf, '[', dim);
945
946         c = get_array_class(utf_new(namebuf, namelen),
947                                                 element->classloader,
948                                                 element->classloader,
949                                                 link);
950
951         dump_release(dumpsize);
952
953         return c;
954 }
955
956
957 /* class_lookup_classref *******************************************************
958
959    Looks up the constant_classref for a given classname in the classref
960    tables of a class.
961
962    IN:
963        cls..............the class containing the reference
964            name.............the name of the class refered to
965
966     RETURN VALUE:
967            a pointer to a constant_classref, or 
968            NULL if the reference was not found
969    
970 *******************************************************************************/
971
972 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
973 {
974         constant_classref *ref;
975         extra_classref *xref;
976         int count;
977
978         assert(cls);
979         assert(name);
980         assert(!cls->classrefcount || cls->classrefs);
981         
982         /* first search the main classref table */
983         count = cls->classrefcount;
984         ref = cls->classrefs;
985         for (; count; --count, ++ref)
986                 if (ref->name == name)
987                         return ref;
988
989         /* next try the list of extra classrefs */
990         for (xref = cls->extclassrefs; xref; xref = xref->next) {
991                 if (xref->classref.name == name)
992                         return &(xref->classref);
993         }
994
995         /* not found */
996         return NULL;
997 }
998
999
1000 /* class_get_classref **********************************************************
1001
1002    Returns the constant_classref for a given classname.
1003
1004    IN:
1005        cls..............the class containing the reference
1006            name.............the name of the class refered to
1007
1008    RETURN VALUE:
1009        a pointer to a constant_classref (never NULL)
1010
1011    NOTE:
1012        The given name is not checked for validity!
1013    
1014 *******************************************************************************/
1015
1016 constant_classref *class_get_classref(classinfo *cls, utf *name)
1017 {
1018         constant_classref *ref;
1019         extra_classref *xref;
1020
1021         assert(cls);
1022         assert(name);
1023
1024         ref = class_lookup_classref(cls,name);
1025         if (ref)
1026                 return ref;
1027
1028         xref = NEW(extra_classref);
1029         CLASSREF_INIT(xref->classref,cls,name);
1030
1031         xref->next = cls->extclassrefs;
1032         cls->extclassrefs = xref;
1033
1034         return &(xref->classref);
1035 }
1036
1037
1038 /* class_get_self_classref *****************************************************
1039
1040    Returns the constant_classref to the class itself.
1041
1042    IN:
1043        cls..............the class containing the reference
1044
1045    RETURN VALUE:
1046        a pointer to a constant_classref (never NULL)
1047
1048 *******************************************************************************/
1049
1050 constant_classref *class_get_self_classref(classinfo *cls)
1051 {
1052         /* XXX this should be done in a faster way. Maybe always make */
1053         /* the classref of index 0 a self reference.                  */
1054         return class_get_classref(cls,cls->name);
1055 }
1056
1057 /* class_get_classref_multiarray_of ********************************************
1058
1059    Returns an array type reference with the given dimension and element class
1060    reference.
1061
1062    IN:
1063        dim..............the requested dimension
1064                             dim must be in [1;255]. This is NOT checked!
1065            ref..............the component class reference
1066
1067    RETURN VALUE:
1068        a pointer to the class reference for the array type
1069
1070    NOTE:
1071        The referer of `ref` is used as the referer for the new classref.
1072
1073 *******************************************************************************/
1074
1075 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1076 {
1077     s4 namelen;
1078     char *namebuf;
1079         s4 dumpsize;
1080         constant_classref *cr;
1081
1082         assert(ref);
1083         assert(dim >= 1 && dim <= 255);
1084
1085         dumpsize = dump_size();
1086
1087     /* Assemble the array class name */
1088     namelen = ref->name->blength;
1089     
1090     if (ref->name->text[0] == '[') {
1091         /* the element is itself an array */
1092         namebuf = DMNEW(char, namelen + dim);
1093         memcpy(namebuf + dim, ref->name->text, namelen);
1094         namelen += dim;
1095     }
1096     else {
1097         /* the element is a non-array class */
1098         namebuf = DMNEW(char, namelen + 2 + dim);
1099         namebuf[dim] = 'L';
1100         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1101         namelen += (2 + dim);
1102         namebuf[namelen - 1] = ';';
1103     }
1104         memset(namebuf, '[', dim);
1105
1106     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1107
1108         dump_release(dumpsize);
1109
1110         return cr;
1111 }
1112
1113
1114 /* class_get_classref_component_of *********************************************
1115
1116    Returns the component classref of a given array type reference
1117
1118    IN:
1119        ref..............the array type reference
1120
1121    RETURN VALUE:
1122        a reference to the component class, or
1123            NULL if `ref` is not an object array type reference
1124
1125    NOTE:
1126        The referer of `ref` is used as the referer for the new classref.
1127
1128 *******************************************************************************/
1129
1130 constant_classref *class_get_classref_component_of(constant_classref *ref)
1131 {
1132         s4 namelen;
1133         char *name;
1134         
1135         assert(ref);
1136
1137         name = ref->name->text;
1138         if (*name++ != '[')
1139                 return NULL;
1140         
1141         namelen = ref->name->blength - 1;
1142         if (*name == 'L') {
1143                 name++;
1144                 namelen -= 2;
1145         }
1146         else if (*name != '[') {
1147                 return NULL;
1148         }
1149
1150     return class_get_classref(ref->referer, utf_new(name, namelen));
1151 }
1152
1153
1154 /* class_findmethod ************************************************************
1155         
1156    Searches a 'classinfo' structure for a method having the given name
1157    and descriptor. If descriptor is NULL, it is ignored.
1158
1159 *******************************************************************************/
1160
1161 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1162 {
1163         methodinfo *m;
1164         s4          i;
1165
1166         for (i = 0; i < c->methodscount; i++) {
1167                 m = &(c->methods[i]);
1168
1169                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1170                         return m;
1171         }
1172
1173         return NULL;
1174 }
1175
1176
1177 /* class_resolvemethod *********************************************************
1178         
1179    Searches a class and it's super classes for a method.
1180
1181    Superinterfaces are *not* searched.
1182
1183 *******************************************************************************/
1184
1185 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1186 {
1187         methodinfo *m;
1188
1189         while (c) {
1190                 m = class_findmethod(c, name, desc);
1191
1192                 if (m)
1193                         return m;
1194
1195                 /* JVM Specification bug: 
1196
1197                    It is important NOT to resolve special <init> and <clinit>
1198                    methods to super classes or interfaces; yet, this is not
1199                    explicited in the specification.  Section 5.4.3.3 should be
1200                    updated appropriately.  */
1201
1202                 if (name == utf_init || name == utf_clinit)
1203                         return NULL;
1204
1205                 c = c->super.cls;
1206         }
1207
1208         return NULL;
1209 }
1210
1211
1212 /* class_resolveinterfacemethod_intern *****************************************
1213
1214    Internally used helper function. Do not use this directly.
1215
1216 *******************************************************************************/
1217
1218 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1219                                                                                                            utf *name, utf *desc)
1220 {
1221         methodinfo *m;
1222         s4          i;
1223
1224         /* try to find the method in the class */
1225
1226         m = class_findmethod(c, name, desc);
1227
1228         if (m != NULL)
1229                 return m;
1230
1231         /* no method found? try the superinterfaces */
1232
1233         for (i = 0; i < c->interfacescount; i++) {
1234                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1235                                                                                                         name, desc);
1236
1237                 if (m != NULL)
1238                         return m;
1239         }
1240
1241         /* no method found */
1242
1243         return NULL;
1244 }
1245
1246
1247 /* class_resolveclassmethod ****************************************************
1248         
1249    Resolves a reference from REFERER to a method with NAME and DESC in
1250    class C.
1251
1252    If the method cannot be resolved the return value is NULL. If
1253    EXCEPT is true *exceptionptr is set, too.
1254
1255 *******************************************************************************/
1256
1257 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1258                                                                          classinfo *referer, bool throwexception)
1259 {
1260         classinfo  *cls;
1261         methodinfo *m;
1262         s4          i;
1263
1264 /*      if (c->flags & ACC_INTERFACE) { */
1265 /*              if (throwexception) */
1266 /*                      *exceptionptr = */
1267 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1268 /*              return NULL; */
1269 /*      } */
1270
1271         /* try class c and its superclasses */
1272
1273         cls = c;
1274
1275         m = class_resolvemethod(cls, name, desc);
1276
1277         if (m != NULL)
1278                 goto found;
1279
1280         /* try the superinterfaces */
1281
1282         for (i = 0; i < c->interfacescount; i++) {
1283                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1284                                                                                                 name, desc);
1285
1286                 if (m != NULL)
1287                         goto found;
1288         }
1289         
1290         if (throwexception)
1291                 exceptions_throw_nosuchmethoderror(c, name, desc);
1292
1293         return NULL;
1294
1295  found:
1296         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1297                 if (throwexception)
1298                         exceptions_throw_abstractmethoderror();
1299
1300                 return NULL;
1301         }
1302
1303         /* XXX check access rights */
1304
1305         return m;
1306 }
1307
1308
1309 /* class_resolveinterfacemethod ************************************************
1310
1311    Resolves a reference from REFERER to a method with NAME and DESC in
1312    interface C.
1313
1314    If the method cannot be resolved the return value is NULL. If
1315    EXCEPT is true *exceptionptr is set, too.
1316
1317 *******************************************************************************/
1318
1319 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1320                                                                                  classinfo *referer, bool throwexception)
1321 {
1322         methodinfo *mi;
1323
1324         if (!(c->flags & ACC_INTERFACE)) {
1325                 if (throwexception)
1326                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1327
1328                 return NULL;
1329         }
1330
1331         mi = class_resolveinterfacemethod_intern(c, name, desc);
1332
1333         if (mi != NULL)
1334                 return mi;
1335
1336         /* try class java.lang.Object */
1337
1338         mi = class_findmethod(class_java_lang_Object, name, desc);
1339
1340         if (mi != NULL)
1341                 return mi;
1342
1343         if (throwexception)
1344                 exceptions_throw_nosuchmethoderror(c, name, desc);
1345
1346         return NULL;
1347 }
1348
1349
1350 /* class_findfield *************************************************************
1351         
1352    Searches for field with specified name and type in a classinfo
1353    structure. If no such field is found NULL is returned.
1354
1355 *******************************************************************************/
1356
1357 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1358 {
1359         s4 i;
1360
1361         for (i = 0; i < c->fieldscount; i++)
1362                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1363                         return &(c->fields[i]);
1364
1365         if (c->super.cls)
1366                 return class_findfield(c->super.cls, name, desc);
1367
1368         return NULL;
1369 }
1370
1371
1372 /* class_findfield_approx ******************************************************
1373         
1374    Searches in 'classinfo'-structure for a field with the specified
1375    name.
1376
1377 *******************************************************************************/
1378  
1379 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1380 {
1381         s4 i;
1382
1383         /* get field index */
1384
1385         i = class_findfield_index_by_name(c, name);
1386
1387         /* field was not found, return */
1388
1389         if (i == -1)
1390                 return NULL;
1391
1392         /* return field address */
1393
1394         return &(c->fields[i]);
1395 }
1396
1397
1398 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1399 {
1400         s4 i;
1401
1402         for (i = 0; i < c->fieldscount; i++) {
1403                 /* compare field names */
1404
1405                 if ((c->fields[i].name == name))
1406                         return i;
1407         }
1408
1409         /* field was not found, raise exception */      
1410
1411         exceptions_throw_nosuchfielderror(c, name);
1412
1413         return -1;
1414 }
1415
1416
1417 /****************** Function: class_resolvefield_int ***************************
1418
1419     This is an internally used helper function. Do not use this directly.
1420
1421         Tries to resolve a field having the given name and type.
1422     If the field cannot be resolved, NULL is returned.
1423
1424 *******************************************************************************/
1425
1426 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1427 {
1428         fieldinfo *fi;
1429         s4         i;
1430
1431         /* search for field in class c */
1432
1433         for (i = 0; i < c->fieldscount; i++) { 
1434                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1435                         return &(c->fields[i]);
1436                 }
1437     }
1438
1439         /* try superinterfaces recursively */
1440
1441         for (i = 0; i < c->interfacescount; i++) {
1442                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1443                 if (fi)
1444                         return fi;
1445         }
1446
1447         /* try superclass */
1448
1449         if (c->super.cls)
1450                 return class_resolvefield_int(c->super.cls, name, desc);
1451
1452         /* not found */
1453
1454         return NULL;
1455 }
1456
1457
1458 /********************* Function: class_resolvefield ***************************
1459         
1460         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1461
1462     If the field cannot be resolved the return value is NULL. If EXCEPT is
1463     true *exceptionptr is set, too.
1464
1465 *******************************************************************************/
1466
1467 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1468                                                           classinfo *referer, bool throwexception)
1469 {
1470         fieldinfo *fi;
1471
1472         fi = class_resolvefield_int(c, name, desc);
1473
1474         if (!fi) {
1475                 if (throwexception)
1476                         exceptions_throw_nosuchfielderror(c, name);
1477
1478                 return NULL;
1479         }
1480
1481         /* XXX check access rights */
1482
1483         return fi;
1484 }
1485
1486
1487 /* class_resolve_superclass ****************************************************
1488
1489    Resolves the super class reference of the given class if necessary.
1490
1491 *******************************************************************************/
1492
1493 static classinfo *class_resolve_superclass(classinfo *c)
1494 {
1495         classinfo *super;
1496
1497         if (c->super.any == NULL)
1498                 return NULL;
1499
1500         /* Do we have a super class reference or is it already
1501            resolved? */
1502
1503         if (IS_CLASSREF(c->super)) {
1504                 super = resolve_classref_or_classinfo_eager(c->super, true);
1505
1506                 if (super == NULL)
1507                         return NULL;
1508
1509                 /* Store the resolved super class in the class structure. */
1510
1511                 c->super.cls = super;
1512         }
1513
1514         return c->super.cls;
1515 }
1516
1517
1518 /* class_issubclass ************************************************************
1519
1520    Checks if sub is a descendant of super.
1521         
1522 *******************************************************************************/
1523
1524 bool class_issubclass(classinfo *sub, classinfo *super)
1525 {
1526         for (;;) {
1527                 if (sub == NULL)
1528                         return false;
1529
1530                 if (sub == super)
1531                         return true;
1532
1533                 sub = class_resolve_superclass(sub);
1534         }
1535 }
1536
1537
1538 /* class_isanysubclass *********************************************************
1539
1540    Checks a subclass relation between two classes. Implemented
1541    interfaces are interpreted as super classes.
1542
1543    Return value: 1 ... sub is subclass of super
1544                  0 ... otherwise
1545
1546 *******************************************************************************/
1547
1548 bool class_isanysubclass(classinfo *sub, classinfo *super)
1549 {
1550         castinfo classvalues;
1551         u4       diffval;
1552         bool     result;
1553
1554         /* This is the trivial case. */
1555
1556         if (sub == super)
1557                 return true;
1558
1559         /* Primitive classes are only subclasses of themselves. */
1560
1561         if (class_is_primitive(sub) || class_is_primitive(super))
1562                 return false;
1563
1564         /* Check for interfaces. */
1565
1566         if (super->flags & ACC_INTERFACE) {
1567                 result = (sub->vftbl->interfacetablelength > super->index) &&
1568                         (sub->vftbl->interfacetable[-super->index] != NULL);
1569         }
1570         else {
1571                 /* java.lang.Object is the only super class of any
1572                    interface. */
1573
1574                 if (sub->flags & ACC_INTERFACE)
1575                         return (super == class_java_lang_Object);
1576
1577                 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1578
1579                 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1580                 result  = diffval <= (u4) classvalues.super_diffval;
1581         }
1582
1583         return result;
1584 }
1585
1586
1587 /* class_is_primitive **********************************************************
1588
1589    Checks if the given class is a primitive class.
1590
1591 *******************************************************************************/
1592
1593 bool class_is_primitive(classinfo *c)
1594 {
1595         if (c->flags & ACC_CLASS_PRIMITIVE)
1596                 return true;
1597
1598         return false;
1599 }
1600
1601
1602 /* class_is_array **************************************************************
1603
1604    Checks if the given class is an array class.
1605
1606 *******************************************************************************/
1607
1608 bool class_is_array(classinfo *c)
1609 {
1610         if (!(c->state & CLASS_LINKED))
1611                 if (!link_class(c))
1612                         return false;
1613
1614         return (c->vftbl->arraydesc != NULL);
1615 }
1616
1617
1618 /* class_is_interface **********************************************************
1619
1620    Checks if the given class is an interface.
1621
1622 *******************************************************************************/
1623
1624 bool class_is_interface(classinfo *c)
1625 {
1626         if (c->flags & ACC_INTERFACE)
1627                 return true;
1628
1629         return false;
1630 }
1631
1632
1633 /* class_get_superclass ********************************************************
1634
1635    Return the super class of the given class.  If the super-field is a
1636    class-reference, resolve it and store it in the classinfo.
1637
1638 *******************************************************************************/
1639
1640 classinfo *class_get_superclass(classinfo *c)
1641 {
1642         classinfo *super;
1643
1644         /* For java.lang.Object, primitive and Void classes we return
1645            NULL. */
1646
1647         if (c->super.any == NULL)
1648                 return NULL;
1649
1650         /* For interfaces we also return NULL. */
1651
1652         if (c->flags & ACC_INTERFACE)
1653                 return NULL;
1654
1655         /* We may have to resolve the super class reference. */
1656
1657         super = class_resolve_superclass(c);
1658
1659         return super;
1660 }
1661
1662
1663 /* class_get_declaringclass ****************************************************
1664
1665    If the class or interface given is a member of another class,
1666    return the declaring class.  For array and primitive classes return
1667    NULL.
1668
1669 *******************************************************************************/
1670
1671 classinfo *class_get_declaringclass(classinfo *c)
1672 {
1673         classref_or_classinfo  innercr;
1674         utf                   *innername;
1675         classref_or_classinfo  outercr;
1676         classinfo             *outer;
1677         int16_t                i;
1678
1679         /* return NULL for arrayclasses and primitive classes */
1680
1681         if (class_is_primitive(c) || (c->name->text[0] == '['))
1682                 return NULL;
1683
1684         /* no innerclasses exist */
1685
1686         if (c->innerclasscount == 0)
1687                 return NULL;
1688
1689         for (i = 0; i < c->innerclasscount; i++) {
1690                 /* Check if inner_class is a classref or a real class and get
1691                    the class name from the structure. */
1692
1693                 innercr = c->innerclass[i].inner_class;
1694
1695                 innername = IS_CLASSREF(innercr) ?
1696                         innercr.ref->name : innercr.cls->name;
1697
1698                 /* Is the current innerclass this class? */
1699
1700                 if (innername == c->name) {
1701                         /* Maybe the outer class is not loaded yet. */
1702
1703                         outercr = c->innerclass[i].outer_class;
1704
1705                         outer = resolve_classref_or_classinfo_eager(outercr, false);
1706
1707                         if (outer == NULL)
1708                                 return NULL;
1709
1710                         if (!(outer->state & CLASS_LINKED))
1711                                 if (!link_class(outer))
1712                                         return NULL;
1713
1714                         return outer;
1715                 }
1716         }
1717
1718         return NULL;
1719 }
1720
1721
1722 /* class_get_signature *********************************************************
1723
1724    Return the signature of the given class.  For array and primitive
1725    classes return NULL.
1726
1727 *******************************************************************************/
1728
1729 #if defined(ENABLE_JAVASE)
1730 utf *class_get_signature(classinfo *c)
1731 {
1732         /* For array and primitive classes return NULL. */
1733
1734         if (class_is_array(c) || class_is_primitive(c))
1735                 return NULL;
1736
1737         return c->signature;
1738 }
1739 #endif
1740
1741
1742 /* class_printflags ************************************************************
1743
1744    Prints flags of a class.
1745
1746 *******************************************************************************/
1747
1748 #if !defined(NDEBUG)
1749 void class_printflags(classinfo *c)
1750 {
1751         if (c == NULL) {
1752                 printf("NULL");
1753                 return;
1754         }
1755
1756         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1757         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1758         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1759         if (c->flags & ACC_STATIC)       printf(" STATIC");
1760         if (c->flags & ACC_FINAL)        printf(" FINAL");
1761         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1762         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1763         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1764         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1765         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1766         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1767 }
1768 #endif
1769
1770
1771 /* class_print *****************************************************************
1772
1773    Prints classname plus flags.
1774
1775 *******************************************************************************/
1776
1777 #if !defined(NDEBUG)
1778 void class_print(classinfo *c)
1779 {
1780         if (c == NULL) {
1781                 printf("NULL");
1782                 return;
1783         }
1784
1785         utf_display_printable_ascii(c->name);
1786         class_printflags(c);
1787 }
1788 #endif
1789
1790
1791 /* class_classref_print ********************************************************
1792
1793    Prints classname plus referer class.
1794
1795 *******************************************************************************/
1796
1797 #if !defined(NDEBUG)
1798 void class_classref_print(constant_classref *cr)
1799 {
1800         if (cr == NULL) {
1801                 printf("NULL");
1802                 return;
1803         }
1804
1805         utf_display_printable_ascii(cr->name);
1806         printf("(ref.by ");
1807         if (cr->referer)
1808                 class_print(cr->referer);
1809         else
1810                 printf("NULL");
1811         printf(")");
1812 }
1813 #endif
1814
1815
1816 /* class_println ***************************************************************
1817
1818    Prints classname plus flags and new line.
1819
1820 *******************************************************************************/
1821
1822 #if !defined(NDEBUG)
1823 void class_println(classinfo *c)
1824 {
1825         class_print(c);
1826         printf("\n");
1827 }
1828 #endif
1829
1830
1831 /* class_classref_println ******************************************************
1832
1833    Prints classname plus referer class and new line.
1834
1835 *******************************************************************************/
1836
1837 #if !defined(NDEBUG)
1838 void class_classref_println(constant_classref *cr)
1839 {
1840         class_classref_print(cr);
1841         printf("\n");
1842 }
1843 #endif
1844
1845
1846 /* class_classref_or_classinfo_print *******************************************
1847
1848    Prints classname plus referer class.
1849
1850 *******************************************************************************/
1851
1852 #if !defined(NDEBUG)
1853 void class_classref_or_classinfo_print(classref_or_classinfo c)
1854 {
1855         if (c.any == NULL) {
1856                 printf("(classref_or_classinfo) NULL");
1857                 return;
1858         }
1859         if (IS_CLASSREF(c))
1860                 class_classref_print(c.ref);
1861         else
1862                 class_print(c.cls);
1863 }
1864 #endif
1865
1866
1867 /* class_classref_or_classinfo_println *****************************************
1868
1869    Prints classname plus referer class and a newline.
1870
1871 *******************************************************************************/
1872
1873 void class_classref_or_classinfo_println(classref_or_classinfo c)
1874 {
1875         class_classref_or_classinfo_println(c);
1876         printf("\n");
1877 }
1878
1879
1880 /* class_showconstantpool ******************************************************
1881
1882    Dump the constant pool of the given class to stdout.
1883
1884 *******************************************************************************/
1885
1886 #if !defined(NDEBUG)
1887 void class_showconstantpool (classinfo *c) 
1888 {
1889         u4 i;
1890         voidptr e;
1891
1892         printf ("---- dump of constant pool ----\n");
1893
1894         for (i=0; i<c->cpcount; i++) {
1895                 printf ("#%d:  ", (int) i);
1896                 
1897                 e = c -> cpinfos [i];
1898                 if (e) {
1899                         
1900                         switch (c -> cptags [i]) {
1901                         case CONSTANT_Class:
1902                                 printf ("Classreference -> ");
1903                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1904                                 break;
1905                         case CONSTANT_Fieldref:
1906                                 printf ("Fieldref -> ");
1907                                 field_fieldref_print((constant_FMIref *) e);
1908                                 break;
1909                         case CONSTANT_Methodref:
1910                                 printf ("Methodref -> ");
1911                                 method_methodref_print((constant_FMIref *) e);
1912                                 break;
1913                         case CONSTANT_InterfaceMethodref:
1914                                 printf ("InterfaceMethod -> ");
1915                                 method_methodref_print((constant_FMIref *) e);
1916                                 break;
1917                         case CONSTANT_String:
1918                                 printf ("String -> ");
1919                                 utf_display_printable_ascii (e);
1920                                 break;
1921                         case CONSTANT_Integer:
1922                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1923                                 break;
1924                         case CONSTANT_Float:
1925                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1926                                 break;
1927                         case CONSTANT_Double:
1928                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1929                                 break;
1930                         case CONSTANT_Long:
1931                                 {
1932                                         u8 v = ((constant_long*)e) -> value;
1933 #if U8_AVAILABLE
1934                                         printf ("Long -> %ld", (long int) v);
1935 #else
1936                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1937                                                         (long int) v.high, (long int) v.low);
1938 #endif 
1939                                 }
1940                                 break;
1941                         case CONSTANT_NameAndType:
1942                                 {
1943                                         constant_nameandtype *cnt = e;
1944                                         printf ("NameAndType: ");
1945                                         utf_display_printable_ascii (cnt->name);
1946                                         printf (" ");
1947                                         utf_display_printable_ascii (cnt->descriptor);
1948                                 }
1949                                 break;
1950                         case CONSTANT_Utf8:
1951                                 printf ("Utf8 -> ");
1952                                 utf_display_printable_ascii (e);
1953                                 break;
1954                         default: 
1955                                 log_text("Invalid type of ConstantPool-Entry");
1956                                 assert(0);
1957                         }
1958                 }
1959
1960                 printf ("\n");
1961         }
1962 }
1963 #endif /* !defined(NDEBUG) */
1964
1965
1966 /* class_showmethods ***********************************************************
1967
1968    Dump info about the fields and methods of the given class to stdout.
1969
1970 *******************************************************************************/
1971
1972 #if !defined(NDEBUG)
1973 void class_showmethods (classinfo *c)
1974 {
1975         s4 i;
1976         
1977         printf("--------- Fields and Methods ----------------\n");
1978         printf("Flags: ");
1979         class_printflags(c);
1980         printf("\n");
1981
1982         printf("This: ");
1983         utf_display_printable_ascii(c->name);
1984         printf("\n");
1985
1986         if (c->super.cls) {
1987                 printf("Super: ");
1988                 utf_display_printable_ascii(c->super.cls->name);
1989                 printf ("\n");
1990         }
1991
1992         printf("Index: %d\n", c->index);
1993         
1994         printf("Interfaces:\n");        
1995         for (i = 0; i < c->interfacescount; i++) {
1996                 printf("   ");
1997                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1998                 printf (" (%d)\n", c->interfaces[i].cls->index);
1999         }
2000
2001         printf("Fields:\n");
2002         for (i = 0; i < c->fieldscount; i++)
2003                 field_println(&(c->fields[i]));
2004
2005         printf("Methods:\n");
2006         for (i = 0; i < c->methodscount; i++) {
2007                 methodinfo *m = &(c->methods[i]);
2008
2009                 if (!(m->flags & ACC_STATIC))
2010                         printf("vftblindex: %d   ", m->vftblindex);
2011
2012                 method_println(m);
2013         }
2014
2015         printf ("Virtual function table:\n");
2016         for (i = 0; i < c->vftbl->vftbllength; i++)
2017                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2018 }
2019 #endif /* !defined(NDEBUG) */
2020
2021
2022 /*
2023  * These are local overrides for various environment variables in Emacs.
2024  * Please do not remove this and leave it at the end of the file, where
2025  * Emacs will automagically detect them.
2026  * ---------------------------------------------------------------------
2027  * Local variables:
2028  * mode: c
2029  * indent-tabs-mode: t
2030  * c-basic-offset: 4
2031  * tab-width: 4
2032  * End:
2033  * vim:noexpandtab:sw=4:ts=4:
2034  */