* src/vm/jit/show.c (show_method): Show maxinterfaces only for stage
[cacao.git] / src / vm / class.c
1 /* src/vm/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Reinhard Grafl
28
29    Changes: Mark Probst
30             Andreas Krall
31             Christian Thalinger
32                         Edwin Steiner
33
34    $Id: class.c 5844 2006-10-28 12:49:29Z edwin $
35
36 */
37
38
39 #include "config.h"
40
41 #include <assert.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 #include "vm/types.h"
46
47 #include "mm/memory.h"
48
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/threads.h"
51 #endif
52
53 #include "toolbox/logging.h"
54 #include "vm/class.h"
55 #include "vm/classcache.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/resolve.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
63 #include "vm/utf8.h"
64
65
66 /* global variables ***********************************************************/
67
68 list unlinkedclasses;                   /* this is only used for eager class  */
69                                         /* loading                            */
70
71
72 /* frequently used classes ****************************************************/
73
74 /* important system classes */
75
76 classinfo *class_java_lang_Object;
77 classinfo *class_java_lang_Class;
78 classinfo *class_java_lang_ClassLoader;
79 classinfo *class_java_lang_Cloneable;
80 classinfo *class_java_lang_SecurityManager;
81 classinfo *class_java_lang_String;
82 classinfo *class_java_lang_System;
83 classinfo *class_java_lang_Thread;
84 classinfo *class_java_lang_ThreadGroup;
85 classinfo *class_java_lang_VMSystem;
86 classinfo *class_java_lang_VMThread;
87 classinfo *class_java_io_Serializable;
88
89
90 /* system exception classes required in cacao */
91
92 classinfo *class_java_lang_Throwable;
93 classinfo *class_java_lang_VMThrowable;
94 classinfo *class_java_lang_Error;
95 classinfo *class_java_lang_AbstractMethodError;
96 classinfo *class_java_lang_LinkageError;
97 classinfo *class_java_lang_NoClassDefFoundError;
98 classinfo *class_java_lang_NoSuchMethodError;
99 classinfo *class_java_lang_OutOfMemoryError;
100
101 classinfo *class_java_lang_Exception;
102 classinfo *class_java_lang_ClassCastException;
103 classinfo *class_java_lang_ClassNotFoundException;
104 classinfo *class_java_lang_IllegalArgumentException;
105 classinfo *class_java_lang_IllegalMonitorStateException;
106
107 classinfo *class_java_lang_Void;
108 classinfo *class_java_lang_Boolean;
109 classinfo *class_java_lang_Byte;
110 classinfo *class_java_lang_Character;
111 classinfo *class_java_lang_Short;
112 classinfo *class_java_lang_Integer;
113 classinfo *class_java_lang_Long;
114 classinfo *class_java_lang_Float;
115 classinfo *class_java_lang_Double;
116
117
118 /* some runtime exception */
119
120 classinfo *class_java_lang_NullPointerException;
121
122
123 /* some classes which may be used more often */
124
125 classinfo *class_java_lang_StackTraceElement;
126 classinfo *class_java_lang_reflect_Constructor;
127 classinfo *class_java_lang_reflect_Field;
128 classinfo *class_java_lang_reflect_Method;
129 classinfo *class_java_security_PrivilegedAction;
130 classinfo *class_java_util_Vector;
131
132 classinfo *arrayclass_java_lang_Object;
133
134
135 /* pseudo classes for the typechecker */
136
137 classinfo *pseudo_class_Arraystub;
138 classinfo *pseudo_class_Null;
139 classinfo *pseudo_class_New;
140
141
142 /* class_set_packagename *******************************************************
143
144    Derive the package name from the class name and store it in the struct.
145
146 *******************************************************************************/
147
148 void class_set_packagename(classinfo *c)
149 {
150         char *p = UTF_END(c->name) - 1;
151         char *start = c->name->text;
152
153         /* set the package name */
154         /* classes in the unnamed package keep packagename == NULL */
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                 if (*start == 'L')
163                         start++;
164
165                 for (; (p > start) && (*p != '/'); --p);
166
167                 c->packagename = utf_new(start, p - start);
168
169         } else {
170                 for (; (p > start) && (*p != '/'); --p);
171
172                 c->packagename = utf_new(start, p - start);
173         }
174 }
175
176
177 /* class_create_classinfo ******************************************************
178
179    Create a new classinfo struct. The class name is set to the given utf *,
180    most other fields are initialized to zero.
181
182    Note: classname may be NULL. In this case a not-yet-named classinfo is
183          created. The name must be filled in later and class_set_packagename
184                  must be called after that.
185
186 *******************************************************************************/
187
188 classinfo *class_create_classinfo(utf *classname)
189 {
190         classinfo *c;
191
192 #if defined(ENABLE_STATISTICS)
193         if (opt_stat)
194                 size_classinfo += sizeof(classinfo);
195 #endif
196
197         /* we use a safe name for temporarily unnamed classes */
198         if (!classname)
199                 classname = utf_not_named_yet;
200
201 #if !defined(NDEBUG)
202         if (initverbose)
203                 log_message_utf("Creating class: ", classname);
204 #endif
205
206         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
207
208         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
209         /*c=NEW(classinfo);*/
210         c->name = classname;
211
212         /* set the header.vftbl of all loaded classes to the one of
213        java.lang.Class, so Java code can use a class as object */
214
215         if (class_java_lang_Class)
216                 if (class_java_lang_Class->vftbl)
217                         c->object.header.vftbl = class_java_lang_Class->vftbl;
218         
219         if (classname != utf_not_named_yet)
220                 class_set_packagename(c);
221
222 #if defined(ENABLE_THREADS)
223         lock_init_object_lock(&c->object.header);
224 #endif
225
226         return c;
227 }
228
229
230 /* class_postset_header_vftbl **************************************************
231
232    Set the header.vftbl of all classes created before java.lang.Class
233    was linked.  This is necessary that Java code can use a class as
234    object.
235
236 *******************************************************************************/
237
238 void class_postset_header_vftbl(void)
239 {
240         classinfo *c;
241         u4 slot;
242         classcache_name_entry *nmen;
243         classcache_class_entry *clsen;
244
245         assert(class_java_lang_Class);
246
247         for (slot = 0; slot < hashtable_classcache.size; slot++) {
248                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
249
250                 for (; nmen; nmen = nmen->hashlink) {
251                         /* iterate over all class entries */
252
253                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
254                                 c = clsen->classobj;
255
256                                 /* now set the the vftbl */
257
258                                 if (c->object.header.vftbl == NULL)
259                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
260                         }
261                 }
262         }
263 }
264
265
266 /* class_freepool **************************************************************
267
268         Frees all resources used by this classes Constant Pool.
269
270 *******************************************************************************/
271
272 static void class_freecpool(classinfo *c)
273 {
274         u4 idx;
275         u4 tag;
276         voidptr info;
277         
278         if (c->cptags && c->cpinfos) {
279                 for (idx = 0; idx < c->cpcount; idx++) {
280                         tag = c->cptags[idx];
281                         info = c->cpinfos[idx];
282                 
283                         if (info != NULL) {
284                                 switch (tag) {
285                                 case CONSTANT_Fieldref:
286                                 case CONSTANT_Methodref:
287                                 case CONSTANT_InterfaceMethodref:
288                                         FREE(info, constant_FMIref);
289                                         break;
290                                 case CONSTANT_Integer:
291                                         FREE(info, constant_integer);
292                                         break;
293                                 case CONSTANT_Float:
294                                         FREE(info, constant_float);
295                                         break;
296                                 case CONSTANT_Long:
297                                         FREE(info, constant_long);
298                                         break;
299                                 case CONSTANT_Double:
300                                         FREE(info, constant_double);
301                                         break;
302                                 case CONSTANT_NameAndType:
303                                         FREE(info, constant_nameandtype);
304                                         break;
305                                 }
306                         }
307                 }
308         }
309
310         if (c->cptags)
311                 MFREE(c->cptags, u1, c->cpcount);
312
313         if (c->cpinfos)
314                 MFREE(c->cpinfos, voidptr, c->cpcount);
315 }
316
317
318 /* class_getconstant ***********************************************************
319
320    Retrieves the value at position 'pos' of the constantpool of a
321    class. If the type of the value is other than 'ctype', an error is
322    thrown.
323
324 *******************************************************************************/
325
326 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
327 {
328         /* check index and type of constantpool entry */
329         /* (pos == 0 is caught by type comparison) */
330
331         if (pos >= c->cpcount || c->cptags[pos] != ctype) {
332                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
333                 return NULL;
334         }
335
336         return c->cpinfos[pos];
337 }
338
339
340 /* innerclass_getconstant ******************************************************
341
342    Like class_getconstant, but if cptags is ZERO, null is returned.
343         
344 *******************************************************************************/
345
346 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
347 {
348         /* invalid position in constantpool */
349         if (pos >= c->cpcount) {
350                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
351                 return NULL;
352         }
353
354         /* constantpool entry of type 0 */      
355         if (!c->cptags[pos])
356                 return NULL;
357
358         /* check type of constantpool entry */
359         if (c->cptags[pos] != ctype) {
360                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
361                 return NULL;
362         }
363                 
364         return c->cpinfos[pos];
365 }
366
367
368 /* class_free ******************************************************************
369
370    Frees all resources used by the class.
371
372 *******************************************************************************/
373
374 void class_free(classinfo *c)
375 {
376         s4 i;
377         vftbl_t *v;
378                 
379         class_freecpool(c);
380
381         if (c->interfaces)
382                 MFREE(c->interfaces, classinfo*, c->interfacescount);
383
384         if (c->fields) {
385                 for (i = 0; i < c->fieldscount; i++)
386                         field_free(&(c->fields[i]));
387 /*      MFREE(c->fields, fieldinfo, c->fieldscount); */
388         }
389         
390         if (c->methods) {
391                 for (i = 0; i < c->methodscount; i++)
392                         method_free(&(c->methods[i]));
393                 MFREE(c->methods, methodinfo, c->methodscount);
394         }
395
396         if ((v = c->vftbl) != NULL) {
397                 if (v->arraydesc)
398                         mem_free(v->arraydesc,sizeof(arraydescriptor));
399                 
400                 for (i = 0; i < v->interfacetablelength; i++) {
401                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
402                 }
403                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
404
405                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
406                     sizeof(methodptr*) * (v->interfacetablelength -
407                                          (v->interfacetablelength > 0));
408                 v = (vftbl_t*) (((methodptr*) v) -
409                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
410                 mem_free(v, i);
411         }
412
413         if (c->innerclass)
414                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
415
416         /*      if (c->classvftbl)
417                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
418         
419 /*      GCFREE(c); */
420 }
421
422
423 /* get_array_class *************************************************************
424
425    Returns the array class with the given name for the given
426    classloader, or NULL if an exception occurred.
427
428    Note: This function does eager loading. 
429
430 *******************************************************************************/
431
432 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
433                                                                                         java_objectheader *defloader,bool link)
434 {
435         classinfo *c;
436         
437         /* lookup this class in the classcache */
438         c = classcache_lookup(initloader,name);
439         if (!c)
440                 c = classcache_lookup_defined(defloader,name);
441
442         if (!c) {
443                 /* we have to create it */
444                 c = class_create_classinfo(name);
445                 c = load_newly_created_array(c,initloader);
446                 if (c == NULL)
447                         return NULL;
448         }
449
450         assert(c);
451         assert(c->state & CLASS_LOADED);
452         assert(c->classloader == defloader);
453
454         if (link && !(c->state & CLASS_LINKED))
455                 if (!link_class(c))
456                         return NULL;
457
458         assert(!link || (c->state & CLASS_LINKED));
459
460         return c;
461 }
462
463
464 /* class_array_of **************************************************************
465
466    Returns an array class with the given component class. The array
467    class is dynamically created if neccessary.
468
469 *******************************************************************************/
470
471 classinfo *class_array_of(classinfo *component, bool link)
472 {
473     s4 namelen;
474     char *namebuf;
475         s4 dumpsize;
476         classinfo *c;
477
478         dumpsize = dump_size();
479
480     /* Assemble the array class name */
481     namelen = component->name->blength;
482     
483     if (component->name->text[0] == '[') {
484         /* the component is itself an array */
485         namebuf = DMNEW(char, namelen + 1);
486         namebuf[0] = '[';
487         MCOPY(namebuf + 1, component->name->text, char, namelen);
488         namelen++;
489
490     } else {
491         /* the component is a non-array class */
492         namebuf = DMNEW(char, namelen + 3);
493         namebuf[0] = '[';
494         namebuf[1] = 'L';
495         MCOPY(namebuf + 2, component->name->text, char, namelen);
496         namebuf[2 + namelen] = ';';
497         namelen += 3;
498     }
499
500         c = get_array_class(utf_new(namebuf, namelen),
501                                                 component->classloader,
502                                                 component->classloader,
503                                                 link);
504
505         dump_release(dumpsize);
506
507         return c;
508 }
509
510
511 /* class_multiarray_of *********************************************************
512
513    Returns an array class with the given dimension and element class.
514    The array class is dynamically created if neccessary.
515
516 *******************************************************************************/
517
518 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
519 {
520     s4 namelen;
521     char *namebuf;
522         s4 dumpsize;
523         classinfo *c;
524
525         dumpsize = dump_size();
526
527         if (dim < 1) {
528                 log_text("Invalid array dimension requested");
529                 assert(0);
530         }
531
532     /* Assemble the array class name */
533     namelen = element->name->blength;
534     
535     if (element->name->text[0] == '[') {
536         /* the element is itself an array */
537         namebuf = DMNEW(char, namelen + dim);
538         memcpy(namebuf + dim, element->name->text, namelen);
539         namelen += dim;
540     }
541     else {
542         /* the element is a non-array class */
543         namebuf = DMNEW(char, namelen + 2 + dim);
544         namebuf[dim] = 'L';
545         memcpy(namebuf + dim + 1, element->name->text, namelen);
546         namelen += (2 + dim);
547         namebuf[namelen - 1] = ';';
548     }
549         memset(namebuf, '[', dim);
550
551         c = get_array_class(utf_new(namebuf, namelen),
552                                                 element->classloader,
553                                                 element->classloader,
554                                                 link);
555
556         dump_release(dumpsize);
557
558         return c;
559 }
560
561
562 /* class_lookup_classref *******************************************************
563
564    Looks up the constant_classref for a given classname in the classref
565    tables of a class.
566
567    IN:
568        cls..............the class containing the reference
569            name.............the name of the class refered to
570
571     RETURN VALUE:
572            a pointer to a constant_classref, or 
573            NULL if the reference was not found
574    
575 *******************************************************************************/
576
577 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
578 {
579         constant_classref *ref;
580         extra_classref *xref;
581         int count;
582
583         assert(cls);
584         assert(name);
585         assert(!cls->classrefcount || cls->classrefs);
586         
587         /* first search the main classref table */
588         count = cls->classrefcount;
589         ref = cls->classrefs;
590         for (; count; --count, ++ref)
591                 if (ref->name == name)
592                         return ref;
593
594         /* next try the list of extra classrefs */
595         for (xref = cls->extclassrefs; xref; xref = xref->next) {
596                 if (xref->classref.name == name)
597                         return &(xref->classref);
598         }
599
600         /* not found */
601         return NULL;
602 }
603
604
605 /* class_get_classref **********************************************************
606
607    Returns the constant_classref for a given classname.
608
609    IN:
610        cls..............the class containing the reference
611            name.............the name of the class refered to
612
613    RETURN VALUE:
614        a pointer to a constant_classref (never NULL)
615
616    NOTE:
617        The given name is not checked for validity!
618    
619 *******************************************************************************/
620
621 constant_classref *class_get_classref(classinfo *cls, utf *name)
622 {
623         constant_classref *ref;
624         extra_classref *xref;
625
626         assert(cls);
627         assert(name);
628
629         ref = class_lookup_classref(cls,name);
630         if (ref)
631                 return ref;
632
633         xref = NEW(extra_classref);
634         CLASSREF_INIT(xref->classref,cls,name);
635
636         xref->next = cls->extclassrefs;
637         cls->extclassrefs = xref;
638
639         return &(xref->classref);
640 }
641
642
643 /* class_get_self_classref *****************************************************
644
645    Returns the constant_classref to the class itself.
646
647    IN:
648        cls..............the class containing the reference
649
650    RETURN VALUE:
651        a pointer to a constant_classref (never NULL)
652
653 *******************************************************************************/
654
655 constant_classref *class_get_self_classref(classinfo *cls)
656 {
657         /* XXX this should be done in a faster way. Maybe always make */
658         /* the classref of index 0 a self reference.                  */
659         return class_get_classref(cls,cls->name);
660 }
661
662 /* class_get_classref_multiarray_of ********************************************
663
664    Returns an array type reference with the given dimension and element class
665    reference.
666
667    IN:
668        dim..............the requested dimension
669                             dim must be in [1;255]. This is NOT checked!
670            ref..............the component class reference
671
672    RETURN VALUE:
673        a pointer to the class reference for the array type
674
675    NOTE:
676        The referer of `ref` is used as the referer for the new classref.
677
678 *******************************************************************************/
679
680 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
681 {
682     s4 namelen;
683     char *namebuf;
684         s4 dumpsize;
685         constant_classref *cr;
686
687         assert(ref);
688         assert(dim >= 1 && dim <= 255);
689
690         dumpsize = dump_size();
691
692     /* Assemble the array class name */
693     namelen = ref->name->blength;
694     
695     if (ref->name->text[0] == '[') {
696         /* the element is itself an array */
697         namebuf = DMNEW(char, namelen + dim);
698         memcpy(namebuf + dim, ref->name->text, namelen);
699         namelen += dim;
700     }
701     else {
702         /* the element is a non-array class */
703         namebuf = DMNEW(char, namelen + 2 + dim);
704         namebuf[dim] = 'L';
705         memcpy(namebuf + dim + 1, ref->name->text, namelen);
706         namelen += (2 + dim);
707         namebuf[namelen - 1] = ';';
708     }
709         memset(namebuf, '[', dim);
710
711     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
712
713         dump_release(dumpsize);
714
715         return cr;
716 }
717
718
719 /* class_get_classref_component_of *********************************************
720
721    Returns the component classref of a given array type reference
722
723    IN:
724        ref..............the array type reference
725
726    RETURN VALUE:
727        a reference to the component class, or
728            NULL if `ref` is not an object array type reference
729
730    NOTE:
731        The referer of `ref` is used as the referer for the new classref.
732
733 *******************************************************************************/
734
735 constant_classref *class_get_classref_component_of(constant_classref *ref)
736 {
737         s4 namelen;
738         char *name;
739         
740         assert(ref);
741
742         name = ref->name->text;
743         if (*name++ != '[')
744                 return NULL;
745         
746         namelen = ref->name->blength - 1;
747         if (*name == 'L') {
748                 name++;
749                 namelen -= 2;
750         }
751         else if (*name != '[') {
752                 return NULL;
753         }
754
755     return class_get_classref(ref->referer, utf_new(name, namelen));
756 }
757
758
759 /* class_findmethod ************************************************************
760         
761    Searches a 'classinfo' structure for a method having the given name
762    and descriptor. If descriptor is NULL, it is ignored.
763
764 *******************************************************************************/
765
766 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
767 {
768         methodinfo *m;
769         s4          i;
770
771         for (i = 0; i < c->methodscount; i++) {
772                 m = &(c->methods[i]);
773
774                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
775                         return m;
776         }
777
778         return NULL;
779 }
780
781
782 /* class_resolvemethod *********************************************************
783         
784    Searches a class and it's super classes for a method.
785
786    Superinterfaces are *not* searched.
787
788 *******************************************************************************/
789
790 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
791 {
792         methodinfo *m;
793
794         while (c) {
795                 m = class_findmethod(c, name, desc);
796
797                 if (m)
798                         return m;
799
800                 /* JVM Specification bug: 
801
802                    It is important NOT to resolve special <init> and <clinit>
803                    methods to super classes or interfaces; yet, this is not
804                    explicited in the specification.  Section 5.4.3.3 should be
805                    updated appropriately.  */
806
807                 if (name == utf_init || name == utf_clinit)
808                         return NULL;
809
810                 c = c->super.cls;
811         }
812
813         return NULL;
814 }
815
816
817 /* class_resolveinterfacemethod_intern *****************************************
818
819    Internally used helper function. Do not use this directly.
820
821 *******************************************************************************/
822
823 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
824                                                                                                            utf *name, utf *desc)
825 {
826         methodinfo *m;
827         s4          i;
828
829         /* try to find the method in the class */
830
831         m = class_findmethod(c, name, desc);
832
833         if (m != NULL)
834                 return m;
835
836         /* no method found? try the superinterfaces */
837
838         for (i = 0; i < c->interfacescount; i++) {
839                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
840                                                                                                         name, desc);
841
842                 if (m != NULL)
843                         return m;
844         }
845
846         /* no method found */
847
848         return NULL;
849 }
850
851
852 /* class_resolveclassmethod ****************************************************
853         
854    Resolves a reference from REFERER to a method with NAME and DESC in
855    class C.
856
857    If the method cannot be resolved the return value is NULL. If
858    EXCEPT is true *exceptionptr is set, too.
859
860 *******************************************************************************/
861
862 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
863                                                                          classinfo *referer, bool throwexception)
864 {
865         classinfo  *cls;
866         methodinfo *m;
867         s4          i;
868
869 /*      if (c->flags & ACC_INTERFACE) { */
870 /*              if (throwexception) */
871 /*                      *exceptionptr = */
872 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
873 /*              return NULL; */
874 /*      } */
875
876         /* try class c and its superclasses */
877
878         cls = c;
879
880         m = class_resolvemethod(cls, name, desc);
881
882         if (m != NULL)
883                 goto found;
884
885         /* try the superinterfaces */
886
887         for (i = 0; i < c->interfacescount; i++) {
888                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
889                                                                                                 name, desc);
890
891                 if (m != NULL)
892                         goto found;
893         }
894         
895         if (throwexception)
896                 exceptions_throw_nosuchmethoderror(c, name, desc);
897
898         return NULL;
899
900  found:
901         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
902                 if (throwexception)
903                         exceptions_throw_abstractmethoderror();
904
905                 return NULL;
906         }
907
908         /* XXX check access rights */
909
910         return m;
911 }
912
913
914 /* class_resolveinterfacemethod ************************************************
915
916    Resolves a reference from REFERER to a method with NAME and DESC in
917    interface C.
918
919    If the method cannot be resolved the return value is NULL. If
920    EXCEPT is true *exceptionptr is set, too.
921
922 *******************************************************************************/
923
924 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
925                                                                                  classinfo *referer, bool throwexception)
926 {
927         methodinfo *mi;
928
929         if (!(c->flags & ACC_INTERFACE)) {
930                 if (throwexception)
931                         *exceptionptr =
932                                 new_exception(string_java_lang_IncompatibleClassChangeError);
933
934                 return NULL;
935         }
936
937         mi = class_resolveinterfacemethod_intern(c, name, desc);
938
939         if (mi)
940                 return mi;
941
942         /* try class java.lang.Object */
943
944         mi = class_findmethod(class_java_lang_Object, name, desc);
945
946         if (mi)
947                 return mi;
948
949         if (throwexception)
950                 *exceptionptr =
951                         exceptions_new_nosuchmethoderror(c, name, desc);
952
953         return NULL;
954 }
955
956
957 /* class_findfield *************************************************************
958         
959    Searches for field with specified name and type in a classinfo
960    structure. If no such field is found NULL is returned.
961
962 *******************************************************************************/
963
964 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
965 {
966         s4 i;
967
968         for (i = 0; i < c->fieldscount; i++)
969                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
970                         return &(c->fields[i]);
971
972         if (c->super.cls)
973                 return class_findfield(c->super.cls, name, desc);
974
975         return NULL;
976 }
977
978
979 /* class_findfield_approx ******************************************************
980         
981    Searches in 'classinfo'-structure for a field with the specified
982    name.
983
984 *******************************************************************************/
985  
986 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
987 {
988         s4 i;
989
990         /* get field index */
991
992         i = class_findfield_index_by_name(c, name);
993
994         /* field was not found, return */
995
996         if (i == -1)
997                 return NULL;
998
999         /* return field address */
1000
1001         return &(c->fields[i]);
1002 }
1003
1004
1005 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1006 {
1007         s4 i;
1008
1009         for (i = 0; i < c->fieldscount; i++) {
1010                 /* compare field names */
1011
1012                 if ((c->fields[i].name == name))
1013                         return i;
1014         }
1015
1016         /* field was not found, raise exception */      
1017
1018         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
1019
1020         return -1;
1021 }
1022
1023
1024 /****************** Function: class_resolvefield_int ***************************
1025
1026     This is an internally used helper function. Do not use this directly.
1027
1028         Tries to resolve a field having the given name and type.
1029     If the field cannot be resolved, NULL is returned.
1030
1031 *******************************************************************************/
1032
1033 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1034 {
1035         fieldinfo *fi;
1036         s4         i;
1037
1038         /* search for field in class c */
1039
1040         for (i = 0; i < c->fieldscount; i++) { 
1041                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1042                         return &(c->fields[i]);
1043                 }
1044     }
1045
1046         /* try superinterfaces recursively */
1047
1048         for (i = 0; i < c->interfacescount; i++) {
1049                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1050                 if (fi)
1051                         return fi;
1052         }
1053
1054         /* try superclass */
1055
1056         if (c->super.cls)
1057                 return class_resolvefield_int(c->super.cls, name, desc);
1058
1059         /* not found */
1060
1061         return NULL;
1062 }
1063
1064
1065 /********************* Function: class_resolvefield ***************************
1066         
1067         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1068
1069     If the field cannot be resolved the return value is NULL. If EXCEPT is
1070     true *exceptionptr is set, too.
1071
1072 *******************************************************************************/
1073
1074 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1075                                                           classinfo *referer, bool throwexception)
1076 {
1077         fieldinfo *fi;
1078
1079         fi = class_resolvefield_int(c, name, desc);
1080
1081         if (!fi) {
1082                 if (throwexception)
1083                         *exceptionptr =
1084                                 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
1085                                                                                  name);
1086
1087                 return NULL;
1088         }
1089
1090         /* XXX check access rights */
1091
1092         return fi;
1093 }
1094
1095
1096 /* class_issubclass ************************************************************
1097
1098    Checks if sub is a descendant of super.
1099         
1100 *******************************************************************************/
1101
1102 bool class_issubclass(classinfo *sub, classinfo *super)
1103 {
1104         for (;;) {
1105                 if (!sub)
1106                         return false;
1107
1108                 if (sub == super)
1109                         return true;
1110
1111                 sub = sub->super.cls;
1112         }
1113 }
1114
1115
1116 /* class_printflags ************************************************************
1117
1118    Prints flags of a class.
1119
1120 *******************************************************************************/
1121
1122 #if !defined(NDEBUG)
1123 void class_printflags(classinfo *c)
1124 {
1125         if (c == NULL) {
1126                 printf("NULL");
1127                 return;
1128         }
1129
1130         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1131         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1132         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1133         if (c->flags & ACC_STATIC)       printf(" STATIC");
1134         if (c->flags & ACC_FINAL)        printf(" FINAL");
1135         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1136         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1137         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1138         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1139         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1140         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1141 }
1142 #endif
1143
1144
1145 /* class_print *****************************************************************
1146
1147    Prints classname plus flags.
1148
1149 *******************************************************************************/
1150
1151 #if !defined(NDEBUG)
1152 void class_print(classinfo *c)
1153 {
1154         if (c == NULL) {
1155                 printf("NULL");
1156                 return;
1157         }
1158
1159         utf_display_printable_ascii(c->name);
1160         class_printflags(c);
1161 }
1162 #endif
1163
1164
1165 /* class_classref_print ********************************************************
1166
1167    Prints classname plus referer class.
1168
1169 *******************************************************************************/
1170
1171 #if !defined(NDEBUG)
1172 void class_classref_print(constant_classref *cr)
1173 {
1174         if (cr == NULL) {
1175                 printf("NULL");
1176                 return;
1177         }
1178
1179         utf_display_printable_ascii(cr->name);
1180         printf("(ref.by ");
1181         if (cr->referer)
1182                 class_print(cr->referer);
1183         else
1184                 printf("NULL");
1185         printf(")");
1186 }
1187 #endif
1188
1189
1190 /* class_println ***************************************************************
1191
1192    Prints classname plus flags and new line.
1193
1194 *******************************************************************************/
1195
1196 #if !defined(NDEBUG)
1197 void class_println(classinfo *c)
1198 {
1199         class_print(c);
1200         printf("\n");
1201 }
1202 #endif
1203
1204
1205 /* class_classref_println ******************************************************
1206
1207    Prints classname plus referer class and new line.
1208
1209 *******************************************************************************/
1210
1211 #if !defined(NDEBUG)
1212 void class_classref_println(constant_classref *cr)
1213 {
1214         class_classref_print(cr);
1215         printf("\n");
1216 }
1217 #endif
1218
1219
1220 /* class_classref_or_classinfo_print *******************************************
1221
1222    Prints classname plus referer class.
1223
1224 *******************************************************************************/
1225
1226 #if !defined(NDEBUG)
1227 void class_classref_or_classinfo_print(classref_or_classinfo c)
1228 {
1229         if (c.any == NULL) {
1230                 printf("(classref_or_classinfo) NULL");
1231                 return;
1232         }
1233         if (IS_CLASSREF(c))
1234                 class_classref_print(c.ref);
1235         else
1236                 class_print(c.cls);
1237 }
1238 #endif
1239
1240
1241 /* class_classref_or_classinfo_println *****************************************
1242
1243    Prints classname plus referer class and a newline.
1244
1245 *******************************************************************************/
1246
1247 void class_classref_or_classinfo_println(classref_or_classinfo c)
1248 {
1249         class_classref_or_classinfo_println(c);
1250         printf("\n");
1251 }
1252
1253
1254 /* class_showconstantpool ******************************************************
1255
1256    Dump the constant pool of the given class to stdout.
1257
1258 *******************************************************************************/
1259
1260 #if !defined(NDEBUG)
1261 void class_showconstantpool (classinfo *c) 
1262 {
1263         u4 i;
1264         voidptr e;
1265
1266         printf ("---- dump of constant pool ----\n");
1267
1268         for (i=0; i<c->cpcount; i++) {
1269                 printf ("#%d:  ", (int) i);
1270                 
1271                 e = c -> cpinfos [i];
1272                 if (e) {
1273                         
1274                         switch (c -> cptags [i]) {
1275                         case CONSTANT_Class:
1276                                 printf ("Classreference -> ");
1277                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1278                                 break;
1279                         case CONSTANT_Fieldref:
1280                                 printf ("Fieldref -> ");
1281                                 field_fieldref_print((constant_FMIref *) e);
1282                                 break;
1283                         case CONSTANT_Methodref:
1284                                 printf ("Methodref -> ");
1285                                 method_methodref_print((constant_FMIref *) e);
1286                                 break;
1287                         case CONSTANT_InterfaceMethodref:
1288                                 printf ("InterfaceMethod -> ");
1289                                 method_methodref_print((constant_FMIref *) e);
1290                                 break;
1291                         case CONSTANT_String:
1292                                 printf ("String -> ");
1293                                 utf_display_printable_ascii (e);
1294                                 break;
1295                         case CONSTANT_Integer:
1296                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1297                                 break;
1298                         case CONSTANT_Float:
1299                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1300                                 break;
1301                         case CONSTANT_Double:
1302                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1303                                 break;
1304                         case CONSTANT_Long:
1305                                 {
1306                                         u8 v = ((constant_long*)e) -> value;
1307 #if U8_AVAILABLE
1308                                         printf ("Long -> %ld", (long int) v);
1309 #else
1310                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1311                                                         (long int) v.high, (long int) v.low);
1312 #endif 
1313                                 }
1314                                 break;
1315                         case CONSTANT_NameAndType:
1316                                 {
1317                                         constant_nameandtype *cnt = e;
1318                                         printf ("NameAndType: ");
1319                                         utf_display_printable_ascii (cnt->name);
1320                                         printf (" ");
1321                                         utf_display_printable_ascii (cnt->descriptor);
1322                                 }
1323                                 break;
1324                         case CONSTANT_Utf8:
1325                                 printf ("Utf8 -> ");
1326                                 utf_display_printable_ascii (e);
1327                                 break;
1328                         default: 
1329                                 log_text("Invalid type of ConstantPool-Entry");
1330                                 assert(0);
1331                         }
1332                 }
1333
1334                 printf ("\n");
1335         }
1336 }
1337 #endif /* !defined(NDEBUG) */
1338
1339
1340 /* class_showmethods ***********************************************************
1341
1342    Dump info about the fields and methods of the given class to stdout.
1343
1344 *******************************************************************************/
1345
1346 #if !defined(NDEBUG)
1347 void class_showmethods (classinfo *c)
1348 {
1349         s4 i;
1350         
1351         printf("--------- Fields and Methods ----------------\n");
1352         printf("Flags: ");
1353         class_printflags(c);
1354         printf("\n");
1355
1356         printf("This: ");
1357         utf_display_printable_ascii(c->name);
1358         printf("\n");
1359
1360         if (c->super.cls) {
1361                 printf("Super: ");
1362                 utf_display_printable_ascii(c->super.cls->name);
1363                 printf ("\n");
1364         }
1365
1366         printf("Index: %d\n", c->index);
1367         
1368         printf("Interfaces:\n");        
1369         for (i = 0; i < c->interfacescount; i++) {
1370                 printf("   ");
1371                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1372                 printf (" (%d)\n", c->interfaces[i].cls->index);
1373         }
1374
1375         printf("Fields:\n");
1376         for (i = 0; i < c->fieldscount; i++)
1377                 field_println(&(c->fields[i]));
1378
1379         printf("Methods:\n");
1380         for (i = 0; i < c->methodscount; i++) {
1381                 methodinfo *m = &(c->methods[i]);
1382
1383                 if (!(m->flags & ACC_STATIC))
1384                         printf("vftblindex: %d   ", m->vftblindex);
1385
1386                 method_println(m);
1387         }
1388
1389         printf ("Virtual function table:\n");
1390         for (i = 0; i < c->vftbl->vftbllength; i++)
1391                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1392 }
1393 #endif /* !defined(NDEBUG) */
1394
1395
1396 /*
1397  * These are local overrides for various environment variables in Emacs.
1398  * Please do not remove this and leave it at the end of the file, where
1399  * Emacs will automagically detect them.
1400  * ---------------------------------------------------------------------
1401  * Local variables:
1402  * mode: c
1403  * indent-tabs-mode: t
1404  * c-basic-offset: 4
1405  * tab-width: 4
1406  * End:
1407  * vim:noexpandtab:sw=4:ts=4:
1408  */