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