* Merged with 03e39cff22db.
[cacao.git] / src / vmcore / class.c
1 /* src/vmcore/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
5
6
7    This file is part of CACAO.
8
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2, or (at
12    your option) any later version.
13
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22    02110-1301, USA.
23
24 */
25
26
27 #include "config.h"
28
29 #include <assert.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "vm/types.h"
35
36 #include "arch.h"
37
38 #include "mm/memory.h"
39
40 #include "native/llni.h"
41
42 #include "threads/lock-common.h"
43
44 #include "toolbox/logging.h"
45
46 #include "vm/array.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/resolve.h"
51
52 #include "vm/jit/asmpart.h"
53
54 #include "vmcore/class.h"
55 #include "vmcore/classcache.h"
56 #include "vmcore/linker.h"
57 #include "vmcore/loader.h"
58 #include "vmcore/options.h"
59
60 #if defined(ENABLE_STATISTICS)
61 # include "vmcore/statistics.h"
62 #endif
63
64 #include "vmcore/suck.h"
65 #include "vmcore/utf8.h"
66
67
68 /* global variables ***********************************************************/
69
70 /* frequently used classes ****************************************************/
71
72 /* important system classes */
73
74 classinfo *class_java_lang_Object;
75 classinfo *class_java_lang_Class;
76 classinfo *class_java_lang_ClassLoader;
77 classinfo *class_java_lang_Cloneable;
78 classinfo *class_java_lang_SecurityManager;
79 classinfo *class_java_lang_String;
80 classinfo *class_java_lang_System;
81 classinfo *class_java_lang_Thread;
82 classinfo *class_java_lang_ThreadGroup;
83 classinfo *class_java_lang_Throwable;
84 classinfo *class_java_io_Serializable;
85
86 #if defined(WITH_CLASSPATH_GNU)
87 classinfo *class_java_lang_VMSystem;
88 classinfo *class_java_lang_VMThread;
89 classinfo *class_java_lang_VMThrowable;
90 #endif
91
92 #if defined(WITH_CLASSPATH_SUN)
93 classinfo *class_sun_reflect_MagicAccessorImpl;
94 #endif
95
96 #if defined(ENABLE_JAVASE)
97 classinfo *class_java_lang_Void;
98 #endif
99 classinfo *class_java_lang_Boolean;
100 classinfo *class_java_lang_Byte;
101 classinfo *class_java_lang_Character;
102 classinfo *class_java_lang_Short;
103 classinfo *class_java_lang_Integer;
104 classinfo *class_java_lang_Long;
105 classinfo *class_java_lang_Float;
106 classinfo *class_java_lang_Double;
107
108 /* some classes which may be used more often */
109
110 #if defined(ENABLE_JAVASE)
111 classinfo *class_java_lang_StackTraceElement;
112 classinfo *class_java_lang_reflect_Constructor;
113 classinfo *class_java_lang_reflect_Field;
114 classinfo *class_java_lang_reflect_Method;
115 classinfo *class_java_security_PrivilegedAction;
116 classinfo *class_java_util_Vector;
117 classinfo *class_java_util_HashMap;
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         int32_t            dumpmarker;
890
891         cl = component->classloader;
892
893         DMARKER;
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         DRELEASE;
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         classinfo *c;
937         int32_t    dumpmarker;
938
939         DMARKER;
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         DRELEASE;
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         constant_classref *cr;
1099         int32_t            dumpmarker;
1100
1101         assert(ref);
1102         assert(dim >= 1 && dim <= 255);
1103
1104         DMARKER;
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         DRELEASE;
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_enclosingmethod ***************************************************
1784
1785    Return the enclosing method for the given class.
1786
1787    IN:
1788        c ... class to return the enclosing method for
1789
1790    RETURN:
1791        methodinfo of the enclosing method
1792
1793 *******************************************************************************/
1794
1795 methodinfo *class_get_enclosingmethod(classinfo *c)
1796 {
1797         constant_nameandtype *cn;
1798         classinfo            *ec;
1799         methodinfo           *m;
1800
1801         /* get enclosing class and method */
1802
1803         ec = class_get_enclosingclass(c);
1804         cn = c->enclosingmethod;
1805
1806         /* check for enclosing class and method */
1807
1808         if (ec == NULL)
1809                 return NULL;
1810
1811         if (cn == NULL)
1812                 return NULL;
1813
1814         /* find method in enclosing class */
1815
1816         m = class_findmethod(ec, cn->name, cn->descriptor);
1817
1818         if (m == NULL) {
1819                 exceptions_throw_internalerror("Enclosing method doesn't exist");
1820                 return NULL;
1821         }
1822
1823         return m;
1824 }
1825
1826
1827 /* class_get_interfaces ********************************************************
1828
1829    Return an array of interfaces of the given class.
1830
1831 *******************************************************************************/
1832
1833 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
1834 {
1835         classinfo                 *ic;
1836         java_handle_objectarray_t *oa;
1837         u4                         i;
1838
1839         if (!(c->state & CLASS_LINKED))
1840                 if (!link_class(c))
1841                         return NULL;
1842
1843         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
1844
1845         if (oa == NULL)
1846                 return NULL;
1847
1848         for (i = 0; i < c->interfacescount; i++) {
1849                 ic = c->interfaces[i];
1850
1851                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
1852         }
1853
1854         return oa;
1855 }
1856
1857
1858 /* class_get_annotations *******************************************************
1859
1860    Get the unparsed declared annotations in a byte array
1861    of the given class.
1862
1863    IN:
1864        c........the class of which the annotations should be returned
1865
1866    RETURN VALUE:
1867        The unparsed declared annotations in a byte array
1868        (or NULL if there aren't any).
1869
1870 *******************************************************************************/
1871
1872 java_handle_bytearray_t *class_get_annotations(classinfo *c)
1873 {
1874 #if defined(ENABLE_ANNOTATIONS)
1875         java_handle_t *annotations; /* unparsed annotations */
1876
1877         LLNI_classinfo_field_get(c, annotations, annotations);
1878
1879         return (java_handle_bytearray_t*)annotations;
1880 #else
1881         return NULL;
1882 #endif
1883 }
1884
1885
1886 /* class_get_modifiers *********************************************************
1887
1888    Get the modifier flags of the given class.
1889
1890    IN:
1891        c....the class of which the modifier flags should be returned
1892            ignoreInnerClassesAttrib
1893    RETURN VALUE:
1894        modifier flags
1895
1896 *******************************************************************************/
1897
1898 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
1899 {
1900         classref_or_classinfo  inner;
1901         classref_or_classinfo  outer;
1902         utf                   *innername;
1903         int                    i;
1904
1905         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
1906                 /* search for passed class as inner class */
1907
1908                 for (i = 0; i < c->innerclasscount; i++) {
1909                         inner = c->innerclass[i].inner_class;
1910                         outer = c->innerclass[i].outer_class;
1911
1912                         /* Check if inner is a classref or a real class and get
1913                the name of the structure */
1914
1915                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
1916
1917                         /* innerclass is this class */
1918
1919                         if (innername == c->name) {
1920                                 /* has the class actually an outer class? */
1921
1922                                 if (outer.any)
1923                                         /* return flags got from the outer class file */
1924                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
1925                                 else
1926                                         return c->flags & ACC_CLASS_REFLECT_MASK;
1927                         }
1928                 }
1929         }
1930
1931         /* passed class is no inner class or it was not requested */
1932
1933         return c->flags & ACC_CLASS_REFLECT_MASK;
1934 }
1935
1936
1937 /* class_get_signature *********************************************************
1938
1939    Return the signature of the given class.  For array and primitive
1940    classes return NULL.
1941
1942 *******************************************************************************/
1943
1944 #if defined(ENABLE_JAVASE)
1945 utf *class_get_signature(classinfo *c)
1946 {
1947         /* For array and primitive classes return NULL. */
1948
1949         if (class_is_array(c) || class_is_primitive(c))
1950                 return NULL;
1951
1952         return c->signature;
1953 }
1954 #endif
1955
1956
1957 /* class_printflags ************************************************************
1958
1959    Prints flags of a class.
1960
1961 *******************************************************************************/
1962
1963 #if !defined(NDEBUG)
1964 void class_printflags(classinfo *c)
1965 {
1966         if (c == NULL) {
1967                 printf("NULL");
1968                 return;
1969         }
1970
1971         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1972         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1973         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1974         if (c->flags & ACC_STATIC)       printf(" STATIC");
1975         if (c->flags & ACC_FINAL)        printf(" FINAL");
1976         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1977         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1978         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1979         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1980         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1981         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1982 }
1983 #endif
1984
1985
1986 /* class_print *****************************************************************
1987
1988    Prints classname plus flags.
1989
1990 *******************************************************************************/
1991
1992 #if !defined(NDEBUG)
1993 void class_print(classinfo *c)
1994 {
1995         if (c == NULL) {
1996                 printf("NULL");
1997                 return;
1998         }
1999
2000         utf_display_printable_ascii(c->name);
2001         class_printflags(c);
2002 }
2003 #endif
2004
2005
2006 /* class_classref_print ********************************************************
2007
2008    Prints classname plus referer class.
2009
2010 *******************************************************************************/
2011
2012 #if !defined(NDEBUG)
2013 void class_classref_print(constant_classref *cr)
2014 {
2015         if (cr == NULL) {
2016                 printf("NULL");
2017                 return;
2018         }
2019
2020         utf_display_printable_ascii(cr->name);
2021         printf("(ref.by ");
2022         if (cr->referer)
2023                 class_print(cr->referer);
2024         else
2025                 printf("NULL");
2026         printf(")");
2027 }
2028 #endif
2029
2030
2031 /* class_println ***************************************************************
2032
2033    Prints classname plus flags and new line.
2034
2035 *******************************************************************************/
2036
2037 #if !defined(NDEBUG)
2038 void class_println(classinfo *c)
2039 {
2040         class_print(c);
2041         printf("\n");
2042 }
2043 #endif
2044
2045
2046 /* class_classref_println ******************************************************
2047
2048    Prints classname plus referer class and new line.
2049
2050 *******************************************************************************/
2051
2052 #if !defined(NDEBUG)
2053 void class_classref_println(constant_classref *cr)
2054 {
2055         class_classref_print(cr);
2056         printf("\n");
2057 }
2058 #endif
2059
2060
2061 /* class_classref_or_classinfo_print *******************************************
2062
2063    Prints classname plus referer class.
2064
2065 *******************************************************************************/
2066
2067 #if !defined(NDEBUG)
2068 void class_classref_or_classinfo_print(classref_or_classinfo c)
2069 {
2070         if (c.any == NULL) {
2071                 printf("(classref_or_classinfo) NULL");
2072                 return;
2073         }
2074         if (IS_CLASSREF(c))
2075                 class_classref_print(c.ref);
2076         else
2077                 class_print(c.cls);
2078 }
2079 #endif
2080
2081
2082 /* class_classref_or_classinfo_println *****************************************
2083
2084    Prints classname plus referer class and a newline.
2085
2086 *******************************************************************************/
2087
2088 #if !defined(NDEBUG)
2089 void class_classref_or_classinfo_println(classref_or_classinfo c)
2090 {
2091         class_classref_or_classinfo_print(c);
2092         printf("\n");
2093 }
2094 #endif
2095
2096
2097 /* class_showconstantpool ******************************************************
2098
2099    Dump the constant pool of the given class to stdout.
2100
2101 *******************************************************************************/
2102
2103 #if !defined(NDEBUG)
2104 void class_showconstantpool (classinfo *c) 
2105 {
2106         u4 i;
2107         voidptr e;
2108
2109         printf ("---- dump of constant pool ----\n");
2110
2111         for (i=0; i<c->cpcount; i++) {
2112                 printf ("#%d:  ", (int) i);
2113                 
2114                 e = c -> cpinfos [i];
2115                 if (e) {
2116                         
2117                         switch (c -> cptags [i]) {
2118                         case CONSTANT_Class:
2119                                 printf ("Classreference -> ");
2120                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2121                                 break;
2122                         case CONSTANT_Fieldref:
2123                                 printf ("Fieldref -> ");
2124                                 field_fieldref_print((constant_FMIref *) e);
2125                                 break;
2126                         case CONSTANT_Methodref:
2127                                 printf ("Methodref -> ");
2128                                 method_methodref_print((constant_FMIref *) e);
2129                                 break;
2130                         case CONSTANT_InterfaceMethodref:
2131                                 printf ("InterfaceMethod -> ");
2132                                 method_methodref_print((constant_FMIref *) e);
2133                                 break;
2134                         case CONSTANT_String:
2135                                 printf ("String -> ");
2136                                 utf_display_printable_ascii (e);
2137                                 break;
2138                         case CONSTANT_Integer:
2139                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2140                                 break;
2141                         case CONSTANT_Float:
2142                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2143                                 break;
2144                         case CONSTANT_Double:
2145                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2146                                 break;
2147                         case CONSTANT_Long:
2148                                 {
2149                                         u8 v = ((constant_long*)e) -> value;
2150 #if U8_AVAILABLE
2151                                         printf ("Long -> %ld", (long int) v);
2152 #else
2153                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2154                                                         (long int) v.high, (long int) v.low);
2155 #endif 
2156                                 }
2157                                 break;
2158                         case CONSTANT_NameAndType:
2159                                 {
2160                                         constant_nameandtype *cnt = e;
2161                                         printf ("NameAndType: ");
2162                                         utf_display_printable_ascii (cnt->name);
2163                                         printf (" ");
2164                                         utf_display_printable_ascii (cnt->descriptor);
2165                                 }
2166                                 break;
2167                         case CONSTANT_Utf8:
2168                                 printf ("Utf8 -> ");
2169                                 utf_display_printable_ascii (e);
2170                                 break;
2171                         default: 
2172                                 log_text("Invalid type of ConstantPool-Entry");
2173                                 assert(0);
2174                         }
2175                 }
2176
2177                 printf ("\n");
2178         }
2179 }
2180 #endif /* !defined(NDEBUG) */
2181
2182
2183 /* class_showmethods ***********************************************************
2184
2185    Dump info about the fields and methods of the given class to stdout.
2186
2187 *******************************************************************************/
2188
2189 #if !defined(NDEBUG)
2190 void class_showmethods (classinfo *c)
2191 {
2192         s4 i;
2193         
2194         printf("--------- Fields and Methods ----------------\n");
2195         printf("Flags: ");
2196         class_printflags(c);
2197         printf("\n");
2198
2199         printf("This: ");
2200         utf_display_printable_ascii(c->name);
2201         printf("\n");
2202
2203         if (c->super) {
2204                 printf("Super: ");
2205                 utf_display_printable_ascii(c->super->name);
2206                 printf ("\n");
2207         }
2208
2209         printf("Index: %d\n", c->index);
2210         
2211         printf("Interfaces:\n");        
2212         for (i = 0; i < c->interfacescount; i++) {
2213                 printf("   ");
2214                 utf_display_printable_ascii(c->interfaces[i]->name);
2215                 printf (" (%d)\n", c->interfaces[i]->index);
2216         }
2217
2218         printf("Fields:\n");
2219         for (i = 0; i < c->fieldscount; i++)
2220                 field_println(&(c->fields[i]));
2221
2222         printf("Methods:\n");
2223         for (i = 0; i < c->methodscount; i++) {
2224                 methodinfo *m = &(c->methods[i]);
2225
2226                 if (!(m->flags & ACC_STATIC))
2227                         printf("vftblindex: %d   ", m->vftblindex);
2228
2229                 method_println(m);
2230         }
2231
2232         printf ("Virtual function table:\n");
2233         for (i = 0; i < c->vftbl->vftbllength; i++)
2234                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2235 }
2236 #endif /* !defined(NDEBUG) */
2237
2238
2239 /*
2240  * These are local overrides for various environment variables in Emacs.
2241  * Please do not remove this and leave it at the end of the file, where
2242  * Emacs will automagically detect them.
2243  * ---------------------------------------------------------------------
2244  * Local variables:
2245  * mode: c
2246  * indent-tabs-mode: t
2247  * c-basic-offset: 4
2248  * tab-width: 4
2249  * End:
2250  * vim:noexpandtab:sw=4:ts=4:
2251  */