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