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