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