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