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