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