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