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