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