* Updated header: Added 2006. Changed address of FSF. Changed email
[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
33    $Id: class.c 4357 2006-01-22 23:33:38Z 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 throwexception)
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 (throwexception) */
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 (throwexception)
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 (throwexception)
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 throwexception)
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 (throwexception)
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 (throwexception)
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 throwexception)
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 (throwexception)
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 /* class_printflags ************************************************************
1158
1159    Prints flags of a class.
1160
1161 *******************************************************************************/
1162
1163 #if !defined(NDEBUG)
1164 void class_printflags(classinfo *c)
1165 {
1166         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1167         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1168         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1169         if (c->flags & ACC_STATIC)       printf(" STATIC");
1170         if (c->flags & ACC_FINAL)        printf(" FINAL");
1171         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1172         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1173         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1174         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1175         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1176         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1177 }
1178 #endif
1179
1180
1181 /* class_print *****************************************************************
1182
1183    Prints classname plus flags.
1184
1185 *******************************************************************************/
1186
1187 #if !defined(NDEBUG)
1188 void class_print(classinfo *c)
1189 {
1190         utf_display(c->name);
1191         class_printflags(c);
1192 }
1193 #endif
1194
1195
1196 /* class_println ***************************************************************
1197
1198    Prints classname plus flags and new line.
1199
1200 *******************************************************************************/
1201
1202 #if !defined(NDEBUG)
1203 void class_println(classinfo *c)
1204 {
1205         class_print(c);
1206         printf("\n");
1207 }
1208 #endif
1209
1210
1211 #if !defined(NDEBUG)
1212 void class_showconstanti(classinfo *c, int ii) 
1213 {
1214         u4 i = ii;
1215         voidptr e;
1216                 
1217         e = c->cpinfos [i];
1218         printf ("#%d:  ", (int) i);
1219         if (e) {
1220                 switch (c->cptags [i]) {
1221                 case CONSTANT_Class:
1222                         printf("Classreference -> ");
1223                         utf_display(((constant_classref*)e)->name);
1224                         break;
1225                                 
1226                 case CONSTANT_Fieldref:
1227                         printf("Fieldref -> "); goto displayFMIi;
1228                 case CONSTANT_Methodref:
1229                         printf("Methodref -> "); goto displayFMIi;
1230                 case CONSTANT_InterfaceMethodref:
1231                         printf("InterfaceMethod -> "); goto displayFMIi;
1232                 displayFMIi:
1233                         {
1234                                 constant_FMIref *fmi = e;
1235                                 utf_display(fmi->classref->name);
1236                                 printf(".");
1237                                 utf_display(fmi->name);
1238                                 printf(" ");
1239                                 utf_display(fmi->descriptor);
1240                         }
1241                         break;
1242
1243                 case CONSTANT_String:
1244                         printf("String -> ");
1245                         utf_display(e);
1246                         break;
1247                 case CONSTANT_Integer:
1248                         printf("Integer -> %d", (int) (((constant_integer*)e)->value));
1249                         break;
1250                 case CONSTANT_Float:
1251                         printf("Float -> %f", ((constant_float*)e)->value);
1252                         break;
1253                 case CONSTANT_Double:
1254                         printf("Double -> %f", ((constant_double*)e)->value);
1255                         break;
1256                 case CONSTANT_Long:
1257                         {
1258                                 u8 v = ((constant_long*)e)->value;
1259 #if U8_AVAILABLE
1260                                 printf("Long -> %ld", (long int) v);
1261 #else
1262                                 printf("Long -> HI: %ld, LO: %ld\n", 
1263                                             (long int) v.high, (long int) v.low);
1264 #endif 
1265                         }
1266                         break;
1267                 case CONSTANT_NameAndType:
1268                         { 
1269                                 constant_nameandtype *cnt = e;
1270                                 printf("NameAndType: ");
1271                                 utf_display(cnt->name);
1272                                 printf(" ");
1273                                 utf_display(cnt->descriptor);
1274                         }
1275                         break;
1276                 case CONSTANT_Utf8:
1277                         printf("Utf8 -> ");
1278                         utf_display(e);
1279                         break;
1280                 default: 
1281                         log_text("Invalid type of ConstantPool-Entry");
1282                         assert(0);
1283                 }
1284         }
1285         printf("\n");
1286 }
1287
1288
1289 void class_showconstantpool (classinfo *c) 
1290 {
1291         u4 i;
1292         voidptr e;
1293
1294         printf ("---- dump of constant pool ----\n");
1295
1296         for (i=0; i<c->cpcount; i++) {
1297                 printf ("#%d:  ", (int) i);
1298                 
1299                 e = c -> cpinfos [i];
1300                 if (e) {
1301                         
1302                         switch (c -> cptags [i]) {
1303                         case CONSTANT_Class:
1304                                 printf ("Classreference -> ");
1305                                 utf_display ( ((constant_classref*)e) -> name );
1306                                 break;
1307                                 
1308                         case CONSTANT_Fieldref:
1309                                 printf ("Fieldref -> "); goto displayFMI;
1310                         case CONSTANT_Methodref:
1311                                 printf ("Methodref -> "); goto displayFMI;
1312                         case CONSTANT_InterfaceMethodref:
1313                                 printf ("InterfaceMethod -> "); goto displayFMI;
1314                         displayFMI:
1315                                 {
1316                                         constant_FMIref *fmi = e;
1317                                         utf_display ( fmi->classref->name );
1318                                         printf (".");
1319                                         utf_display ( fmi->name);
1320                                         printf (" ");
1321                                         utf_display ( fmi->descriptor );
1322                                 }
1323                                 break;
1324
1325                         case CONSTANT_String:
1326                                 printf ("String -> ");
1327                                 utf_display (e);
1328                                 break;
1329                         case CONSTANT_Integer:
1330                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1331                                 break;
1332                         case CONSTANT_Float:
1333                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1334                                 break;
1335                         case CONSTANT_Double:
1336                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1337                                 break;
1338                         case CONSTANT_Long:
1339                                 {
1340                                         u8 v = ((constant_long*)e) -> value;
1341 #if U8_AVAILABLE
1342                                         printf ("Long -> %ld", (long int) v);
1343 #else
1344                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1345                                                         (long int) v.high, (long int) v.low);
1346 #endif 
1347                                 }
1348                                 break;
1349                         case CONSTANT_NameAndType:
1350                                 {
1351                                         constant_nameandtype *cnt = e;
1352                                         printf ("NameAndType: ");
1353                                         utf_display (cnt->name);
1354                                         printf (" ");
1355                                         utf_display (cnt->descriptor);
1356                                 }
1357                                 break;
1358                         case CONSTANT_Utf8:
1359                                 printf ("Utf8 -> ");
1360                                 utf_display (e);
1361                                 break;
1362                         default: 
1363                                 log_text("Invalid type of ConstantPool-Entry");
1364                                 assert(0);
1365                         }
1366                 }
1367
1368                 printf ("\n");
1369         }
1370 }
1371
1372
1373
1374 /********** Function: class_showmethods   (debugging only) *************/
1375
1376 void class_showmethods (classinfo *c)
1377 {
1378         s4 i;
1379         
1380         printf("--------- Fields and Methods ----------------\n");
1381         printf("Flags: ");
1382         class_printflags(c);
1383         printf("\n");
1384
1385         printf("This: ");
1386         utf_display(c->name);
1387         printf("\n");
1388
1389         if (c->super.cls) {
1390                 printf("Super: ");
1391                 utf_display(c->super.cls->name);
1392                 printf ("\n");
1393         }
1394
1395         printf("Index: %d\n", c->index);
1396         
1397         printf("Interfaces:\n");        
1398         for (i = 0; i < c->interfacescount; i++) {
1399                 printf("   ");
1400                 utf_display(c->interfaces[i].cls->name);
1401                 printf (" (%d)\n", c->interfaces[i].cls->index);
1402         }
1403
1404         printf("Fields:\n");
1405         for (i = 0; i < c->fieldscount; i++)
1406                 field_println(&(c->fields[i]));
1407
1408         printf("Methods:\n");
1409         for (i = 0; i < c->methodscount; i++) {
1410                 methodinfo *m = &(c->methods[i]);
1411
1412                 if (!(m->flags & ACC_STATIC))
1413                         printf("vftblindex: %d   ", m->vftblindex);
1414
1415                 method_println(m);
1416         }
1417
1418         printf ("Virtual function table:\n");
1419         for (i = 0; i < c->vftbl->vftbllength; i++)
1420                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1421 }
1422 #endif /* !defined(NDEBUG) */
1423
1424
1425 /*
1426  * These are local overrides for various environment variables in Emacs.
1427  * Please do not remove this and leave it at the end of the file, where
1428  * Emacs will automagically detect them.
1429  * ---------------------------------------------------------------------
1430  * Local variables:
1431  * mode: c
1432  * indent-tabs-mode: t
1433  * c-basic-offset: 4
1434  * tab-width: 4
1435  * End:
1436  */