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