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