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