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