* src/vm/string.c (native/jni.h): Added.
[cacao.git] / src / vmcore / class.c
1 /* src/vmcore/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: class.c 7257 2007-01-29 23:07:40Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "vm/types.h"
38
39 #include "mm/memory.h"
40
41 #if defined(ENABLE_THREADS)
42 # include "threads/native/lock.h"
43 #endif
44
45 #include "toolbox/logging.h"
46
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49
50 #include "vmcore/class.h"
51 #include "vmcore/classcache.h"
52 #include "vmcore/loader.h"
53 #include "vmcore/options.h"
54 #include "vmcore/resolve.h"
55
56 #if defined(ENABLE_STATISTICS)
57 # include "vmcore/statistics.h"
58 #endif
59
60 #include "vmcore/suck.h"
61 #include "vmcore/utf8.h"
62
63
64 /* global variables ***********************************************************/
65
66 list unlinkedclasses;                   /* this is only used for eager class  */
67                                         /* loading                            */
68
69
70 /* frequently used classes ****************************************************/
71
72 /* important system classes */
73
74 classinfo *class_java_lang_Object;
75 classinfo *class_java_lang_Class;
76 classinfo *class_java_lang_ClassLoader;
77 classinfo *class_java_lang_Cloneable;
78 classinfo *class_java_lang_SecurityManager;
79 classinfo *class_java_lang_String;
80 classinfo *class_java_lang_System;
81 classinfo *class_java_lang_Thread;
82 classinfo *class_java_lang_ThreadGroup;
83 classinfo *class_java_lang_VMSystem;
84 classinfo *class_java_lang_VMThread;
85 classinfo *class_java_io_Serializable;
86
87
88 /* system exception classes required in cacao */
89
90 classinfo *class_java_lang_Throwable;
91 classinfo *class_java_lang_Error;
92 classinfo *class_java_lang_LinkageError;
93 classinfo *class_java_lang_NoClassDefFoundError;
94 classinfo *class_java_lang_OutOfMemoryError;
95 classinfo *class_java_lang_VirtualMachineError;
96
97 #if defined(WITH_CLASSPATH_GNU)
98 classinfo *class_java_lang_VMThrowable;
99 #endif
100
101 classinfo *class_java_lang_Exception;
102 classinfo *class_java_lang_ClassCastException;
103 classinfo *class_java_lang_ClassNotFoundException;
104
105 #if defined(ENABLE_JAVASE)
106 classinfo *class_java_lang_Void;
107 #endif
108 classinfo *class_java_lang_Boolean;
109 classinfo *class_java_lang_Byte;
110 classinfo *class_java_lang_Character;
111 classinfo *class_java_lang_Short;
112 classinfo *class_java_lang_Integer;
113 classinfo *class_java_lang_Long;
114 classinfo *class_java_lang_Float;
115 classinfo *class_java_lang_Double;
116
117
118 /* some runtime exception */
119
120 classinfo *class_java_lang_NullPointerException;
121
122
123 /* some classes which may be used more often */
124
125 #if defined(ENABLE_JAVASE)
126 classinfo *class_java_lang_StackTraceElement;
127 classinfo *class_java_lang_reflect_Constructor;
128 classinfo *class_java_lang_reflect_Field;
129 classinfo *class_java_lang_reflect_Method;
130 classinfo *class_java_security_PrivilegedAction;
131 classinfo *class_java_util_Vector;
132
133 classinfo *arrayclass_java_lang_Object;
134 #endif
135
136
137 /* pseudo classes for the typechecker */
138
139 classinfo *pseudo_class_Arraystub;
140 classinfo *pseudo_class_Null;
141 classinfo *pseudo_class_New;
142
143
144 /* class_set_packagename *******************************************************
145
146    Derive the package name from the class name and store it in the struct.
147
148 *******************************************************************************/
149
150 void class_set_packagename(classinfo *c)
151 {
152         char *p = UTF_END(c->name) - 1;
153         char *start = c->name->text;
154
155         /* set the package name */
156         /* classes in the unnamed package keep packagename == NULL */
157
158         if (c->name->text[0] == '[') {
159                 /* set packagename of arrays to the element's package */
160
161                 for (; *start == '['; start++);
162
163                 /* skip the 'L' in arrays of references */
164                 if (*start == 'L')
165                         start++;
166
167                 for (; (p > start) && (*p != '/'); --p);
168
169                 c->packagename = utf_new(start, p - start);
170
171         } else {
172                 for (; (p > start) && (*p != '/'); --p);
173
174                 c->packagename = utf_new(start, p - start);
175         }
176 }
177
178
179 /* class_create_classinfo ******************************************************
180
181    Create a new classinfo struct. The class name is set to the given utf *,
182    most other fields are initialized to zero.
183
184    Note: classname may be NULL. In this case a not-yet-named classinfo is
185          created. The name must be filled in later and class_set_packagename
186                  must be called after that.
187
188 *******************************************************************************/
189
190 classinfo *class_create_classinfo(utf *classname)
191 {
192         classinfo *c;
193
194 #if defined(ENABLE_STATISTICS)
195         if (opt_stat)
196                 size_classinfo += sizeof(classinfo);
197 #endif
198
199         /* we use a safe name for temporarily unnamed classes */
200         if (!classname)
201                 classname = utf_not_named_yet;
202
203 #if !defined(NDEBUG)
204         if (initverbose)
205                 log_message_utf("Creating class: ", classname);
206 #endif
207
208         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
209
210         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
211         /*c=NEW(classinfo);*/
212         c->name = classname;
213
214         /* Set the header.vftbl of all loaded classes to the one of
215        java.lang.Class, so Java code can use a class as object. */
216
217         if (class_java_lang_Class)
218                 if (class_java_lang_Class->vftbl)
219                         c->object.header.vftbl = class_java_lang_Class->vftbl;
220         
221         if (classname != utf_not_named_yet)
222                 class_set_packagename(c);
223
224 #if defined(ENABLE_THREADS)
225         lock_init_object_lock(&c->object.header);
226 #endif
227
228         return c;
229 }
230
231
232 /* class_postset_header_vftbl **************************************************
233
234    Set the header.vftbl of all classes created before java.lang.Class
235    was linked.  This is necessary that Java code can use a class as
236    object.
237
238 *******************************************************************************/
239
240 void class_postset_header_vftbl(void)
241 {
242         classinfo *c;
243         u4 slot;
244         classcache_name_entry *nmen;
245         classcache_class_entry *clsen;
246
247         assert(class_java_lang_Class);
248
249         for (slot = 0; slot < hashtable_classcache.size; slot++) {
250                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
251
252                 for (; nmen; nmen = nmen->hashlink) {
253                         /* iterate over all class entries */
254
255                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
256                                 c = clsen->classobj;
257
258                                 /* now set the the vftbl */
259
260                                 if (c->object.header.vftbl == NULL)
261                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
262                         }
263                 }
264         }
265 }
266
267
268 /* class_load_attribute_sourcefile *********************************************
269
270    SourceFile_attribute {
271        u2 attribute_name_index;
272        u4 attribute_length;
273            u2 sourcefile_index;
274    }
275
276 *******************************************************************************/
277
278 static bool class_load_attribute_sourcefile(classbuffer *cb)
279 {
280         classinfo *c;
281         u4         attribute_length;
282         u2         sourcefile_index;
283         utf       *sourcefile;
284
285         /* get classinfo */
286
287         c = cb->class;
288
289         /* check buffer size */
290
291         if (!suck_check_classbuffer_size(cb, 4 + 2))
292                 return false;
293
294         /* check attribute length */
295
296         attribute_length = suck_u4(cb);
297
298         if (attribute_length != 2) {
299                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
300                 return false;
301         }
302
303         /* there can be no more than one SourceFile attribute */
304
305         if (c->sourcefile != NULL) {
306                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
307                 return false;
308         }
309
310         /* get sourcefile */
311
312         sourcefile_index = suck_u2(cb);
313         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
314
315         if (sourcefile == NULL)
316                 return false;
317
318         /* store sourcefile */
319
320         c->sourcefile = sourcefile;
321
322         return true;
323 }
324
325
326 /* class_load_attribute_enclosingmethod ****************************************
327
328    EnclosingMethod_attribute {
329        u2 attribute_name_index;
330        u4 attribute_length;
331            u2 class_index;
332            u2 method_index;
333    }
334
335 *******************************************************************************/
336
337 #if defined(ENABLE_JAVASE)
338 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
339 {
340         classinfo             *c;
341         u4                     attribute_length;
342         u2                     class_index;
343         u2                     method_index;
344         classref_or_classinfo  cr;
345         constant_nameandtype  *cn;
346
347         /* get classinfo */
348
349         c = cb->class;
350
351         /* check buffer size */
352
353         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
354                 return false;
355
356         /* check attribute length */
357
358         attribute_length = suck_u4(cb);
359
360         if (attribute_length != 4) {
361                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
362                 return false;
363         }
364
365         /* there can be no more than one EnclosingMethod attribute */
366
367         if (c->enclosingmethod != NULL) {
368                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
369                 return false;
370         }
371
372         /* get class index */
373
374         class_index = suck_u2(cb);
375         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
376
377         /* get method index */
378
379         method_index = suck_u2(cb);
380         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
381
382         /* store info in classinfo */
383
384         c->enclosingclass.any = cr.any;
385         c->enclosingmethod    = cn;
386
387         return true;
388 }
389 #endif /* defined(ENABLE_JAVASE) */
390
391
392 /* class_load_attributes *******************************************************
393
394    Read attributes from ClassFile.
395
396    attribute_info {
397        u2 attribute_name_index;
398        u4 attribute_length;
399        u1 info[attribute_length];
400    }
401
402    InnerClasses_attribute {
403        u2 attribute_name_index;
404        u4 attribute_length;
405    }
406
407 *******************************************************************************/
408
409 bool class_load_attributes(classbuffer *cb)
410 {
411         classinfo *c;
412         u4         i, j;
413         u2         attributes_count;
414         u2         attribute_name_index;
415         utf       *attribute_name;
416
417         c = cb->class;
418
419         /* get attributes count */
420
421         if (!suck_check_classbuffer_size(cb, 2))
422                 return false;
423
424         attributes_count = suck_u2(cb);
425
426         for (i = 0; i < attributes_count; i++) {
427                 /* get attribute name */
428
429                 if (!suck_check_classbuffer_size(cb, 2))
430                         return false;
431
432                 attribute_name_index = suck_u2(cb);
433                 attribute_name =
434                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
435
436                 if (attribute_name == NULL)
437                         return false;
438
439                 if (attribute_name == utf_InnerClasses) {
440                         /* InnerClasses */
441
442                         if (c->innerclass != NULL) {
443                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
444                                 return false;
445                         }
446                                 
447                         if (!suck_check_classbuffer_size(cb, 4 + 2))
448                                 return false;
449
450                         /* skip attribute length */
451                         suck_u4(cb);
452
453                         /* number of records */
454                         c->innerclasscount = suck_u2(cb);
455
456                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
457                                 return false;
458
459                         /* allocate memory for innerclass structure */
460                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
461
462                         for (j = 0; j < c->innerclasscount; j++) {
463                                 /* The innerclass structure contains a class with an encoded
464                                    name, its defining scope, its simple name and a bitmask of
465                                    the access flags. If an inner class is not a member, its
466                                    outer_class is NULL, if a class is anonymous, its name is
467                                    NULL. */
468                                                                 
469                                 innerclassinfo *info = c->innerclass + j;
470
471                                 info->inner_class.ref =
472                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
473                                 info->outer_class.ref =
474                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
475                                 info->name =
476                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
477                                 info->flags = suck_u2(cb);
478                         }
479                 }
480                 else if (attribute_name == utf_SourceFile) {
481                         /* SourceFile */
482
483                         if (!class_load_attribute_sourcefile(cb))
484                                 return false;
485                 }
486 #if defined(ENABLE_JAVASE)
487                 else if (attribute_name == utf_EnclosingMethod) {
488                         /* EnclosingMethod */
489
490                         if (!class_load_attribute_enclosingmethod(cb))
491                                 return false;
492                 }
493                 else if (attribute_name == utf_Signature) {
494                         /* Signature */
495
496                         if (!loader_load_attribute_signature(cb, &(c->signature)))
497                                 return false;
498                 }
499                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
500                         /* RuntimeVisibleAnnotations */
501
502                         if (!annotation_load_attribute_runtimevisibleannotations(cb))
503                                 return false;
504                 }
505 #endif
506                 else {
507                         /* unknown attribute */
508
509                         if (!loader_skip_attribute_body(cb))
510                                 return false;
511                 }
512         }
513
514         return true;
515 }
516
517
518 /* class_freepool **************************************************************
519
520         Frees all resources used by this classes Constant Pool.
521
522 *******************************************************************************/
523
524 static void class_freecpool(classinfo *c)
525 {
526         u4 idx;
527         u4 tag;
528         voidptr info;
529         
530         if (c->cptags && c->cpinfos) {
531                 for (idx = 0; idx < c->cpcount; idx++) {
532                         tag = c->cptags[idx];
533                         info = c->cpinfos[idx];
534                 
535                         if (info != NULL) {
536                                 switch (tag) {
537                                 case CONSTANT_Fieldref:
538                                 case CONSTANT_Methodref:
539                                 case CONSTANT_InterfaceMethodref:
540                                         FREE(info, constant_FMIref);
541                                         break;
542                                 case CONSTANT_Integer:
543                                         FREE(info, constant_integer);
544                                         break;
545                                 case CONSTANT_Float:
546                                         FREE(info, constant_float);
547                                         break;
548                                 case CONSTANT_Long:
549                                         FREE(info, constant_long);
550                                         break;
551                                 case CONSTANT_Double:
552                                         FREE(info, constant_double);
553                                         break;
554                                 case CONSTANT_NameAndType:
555                                         FREE(info, constant_nameandtype);
556                                         break;
557                                 }
558                         }
559                 }
560         }
561
562         if (c->cptags)
563                 MFREE(c->cptags, u1, c->cpcount);
564
565         if (c->cpinfos)
566                 MFREE(c->cpinfos, voidptr, c->cpcount);
567 }
568
569
570 /* class_getconstant ***********************************************************
571
572    Retrieves the value at position 'pos' of the constantpool of a
573    class. If the type of the value is other than 'ctype', an error is
574    thrown.
575
576 *******************************************************************************/
577
578 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
579 {
580         /* check index and type of constantpool entry */
581         /* (pos == 0 is caught by type comparison) */
582
583         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
584                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
585                 return NULL;
586         }
587
588         return c->cpinfos[pos];
589 }
590
591
592 /* innerclass_getconstant ******************************************************
593
594    Like class_getconstant, but if cptags is ZERO, null is returned.
595         
596 *******************************************************************************/
597
598 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
599 {
600         /* invalid position in constantpool */
601
602         if (pos >= c->cpcount) {
603                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
604                 return NULL;
605         }
606
607         /* constantpool entry of type 0 */      
608
609         if (c->cptags[pos] == 0)
610                 return NULL;
611
612         /* check type of constantpool entry */
613
614         if (c->cptags[pos] != ctype) {
615                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
616                 return NULL;
617         }
618                 
619         return c->cpinfos[pos];
620 }
621
622
623 /* class_free ******************************************************************
624
625    Frees all resources used by the class.
626
627 *******************************************************************************/
628
629 void class_free(classinfo *c)
630 {
631         s4 i;
632         vftbl_t *v;
633                 
634         class_freecpool(c);
635
636         if (c->interfaces)
637                 MFREE(c->interfaces, classinfo*, c->interfacescount);
638
639         if (c->fields) {
640                 for (i = 0; i < c->fieldscount; i++)
641                         field_free(&(c->fields[i]));
642 #if defined(ENABLE_CACAO_GC)
643                 MFREE(c->fields, fieldinfo, c->fieldscount);
644 #endif
645         }
646         
647         if (c->methods) {
648                 for (i = 0; i < c->methodscount; i++)
649                         method_free(&(c->methods[i]));
650                 MFREE(c->methods, methodinfo, c->methodscount);
651         }
652
653         if ((v = c->vftbl) != NULL) {
654                 if (v->arraydesc)
655                         mem_free(v->arraydesc,sizeof(arraydescriptor));
656                 
657                 for (i = 0; i < v->interfacetablelength; i++) {
658                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
659                 }
660                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
661
662                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
663                     sizeof(methodptr*) * (v->interfacetablelength -
664                                          (v->interfacetablelength > 0));
665                 v = (vftbl_t*) (((methodptr*) v) -
666                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
667                 mem_free(v, i);
668         }
669
670         if (c->innerclass)
671                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
672
673         /*      if (c->classvftbl)
674                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
675         
676 /*      GCFREE(c); */
677 }
678
679
680 /* get_array_class *************************************************************
681
682    Returns the array class with the given name for the given
683    classloader, or NULL if an exception occurred.
684
685    Note: This function does eager loading. 
686
687 *******************************************************************************/
688
689 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
690                                                                                         java_objectheader *defloader,bool link)
691 {
692         classinfo *c;
693         
694         /* lookup this class in the classcache */
695         c = classcache_lookup(initloader,name);
696         if (!c)
697                 c = classcache_lookup_defined(defloader,name);
698
699         if (!c) {
700                 /* we have to create it */
701                 c = class_create_classinfo(name);
702                 c = load_newly_created_array(c,initloader);
703                 if (c == NULL)
704                         return NULL;
705         }
706
707         assert(c);
708         assert(c->state & CLASS_LOADED);
709         assert(c->classloader == defloader);
710
711         if (link && !(c->state & CLASS_LINKED))
712                 if (!link_class(c))
713                         return NULL;
714
715         assert(!link || (c->state & CLASS_LINKED));
716
717         return c;
718 }
719
720
721 /* class_array_of **************************************************************
722
723    Returns an array class with the given component class. The array
724    class is dynamically created if neccessary.
725
726 *******************************************************************************/
727
728 classinfo *class_array_of(classinfo *component, bool link)
729 {
730     s4 namelen;
731     char *namebuf;
732         s4 dumpsize;
733         classinfo *c;
734
735         dumpsize = dump_size();
736
737     /* Assemble the array class name */
738     namelen = component->name->blength;
739     
740     if (component->name->text[0] == '[') {
741         /* the component is itself an array */
742         namebuf = DMNEW(char, namelen + 1);
743         namebuf[0] = '[';
744         MCOPY(namebuf + 1, component->name->text, char, namelen);
745         namelen++;
746
747     } else {
748         /* the component is a non-array class */
749         namebuf = DMNEW(char, namelen + 3);
750         namebuf[0] = '[';
751         namebuf[1] = 'L';
752         MCOPY(namebuf + 2, component->name->text, char, namelen);
753         namebuf[2 + namelen] = ';';
754         namelen += 3;
755     }
756
757         c = get_array_class(utf_new(namebuf, namelen),
758                                                 component->classloader,
759                                                 component->classloader,
760                                                 link);
761
762         dump_release(dumpsize);
763
764         return c;
765 }
766
767
768 /* class_multiarray_of *********************************************************
769
770    Returns an array class with the given dimension and element class.
771    The array class is dynamically created if neccessary.
772
773 *******************************************************************************/
774
775 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
776 {
777     s4 namelen;
778     char *namebuf;
779         s4 dumpsize;
780         classinfo *c;
781
782         dumpsize = dump_size();
783
784         if (dim < 1) {
785                 log_text("Invalid array dimension requested");
786                 assert(0);
787         }
788
789     /* Assemble the array class name */
790     namelen = element->name->blength;
791     
792     if (element->name->text[0] == '[') {
793         /* the element is itself an array */
794         namebuf = DMNEW(char, namelen + dim);
795         memcpy(namebuf + dim, element->name->text, namelen);
796         namelen += dim;
797     }
798     else {
799         /* the element is a non-array class */
800         namebuf = DMNEW(char, namelen + 2 + dim);
801         namebuf[dim] = 'L';
802         memcpy(namebuf + dim + 1, element->name->text, namelen);
803         namelen += (2 + dim);
804         namebuf[namelen - 1] = ';';
805     }
806         memset(namebuf, '[', dim);
807
808         c = get_array_class(utf_new(namebuf, namelen),
809                                                 element->classloader,
810                                                 element->classloader,
811                                                 link);
812
813         dump_release(dumpsize);
814
815         return c;
816 }
817
818
819 /* class_lookup_classref *******************************************************
820
821    Looks up the constant_classref for a given classname in the classref
822    tables of a class.
823
824    IN:
825        cls..............the class containing the reference
826            name.............the name of the class refered to
827
828     RETURN VALUE:
829            a pointer to a constant_classref, or 
830            NULL if the reference was not found
831    
832 *******************************************************************************/
833
834 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
835 {
836         constant_classref *ref;
837         extra_classref *xref;
838         int count;
839
840         assert(cls);
841         assert(name);
842         assert(!cls->classrefcount || cls->classrefs);
843         
844         /* first search the main classref table */
845         count = cls->classrefcount;
846         ref = cls->classrefs;
847         for (; count; --count, ++ref)
848                 if (ref->name == name)
849                         return ref;
850
851         /* next try the list of extra classrefs */
852         for (xref = cls->extclassrefs; xref; xref = xref->next) {
853                 if (xref->classref.name == name)
854                         return &(xref->classref);
855         }
856
857         /* not found */
858         return NULL;
859 }
860
861
862 /* class_get_classref **********************************************************
863
864    Returns the constant_classref for a given classname.
865
866    IN:
867        cls..............the class containing the reference
868            name.............the name of the class refered to
869
870    RETURN VALUE:
871        a pointer to a constant_classref (never NULL)
872
873    NOTE:
874        The given name is not checked for validity!
875    
876 *******************************************************************************/
877
878 constant_classref *class_get_classref(classinfo *cls, utf *name)
879 {
880         constant_classref *ref;
881         extra_classref *xref;
882
883         assert(cls);
884         assert(name);
885
886         ref = class_lookup_classref(cls,name);
887         if (ref)
888                 return ref;
889
890         xref = NEW(extra_classref);
891         CLASSREF_INIT(xref->classref,cls,name);
892
893         xref->next = cls->extclassrefs;
894         cls->extclassrefs = xref;
895
896         return &(xref->classref);
897 }
898
899
900 /* class_get_self_classref *****************************************************
901
902    Returns the constant_classref to the class itself.
903
904    IN:
905        cls..............the class containing the reference
906
907    RETURN VALUE:
908        a pointer to a constant_classref (never NULL)
909
910 *******************************************************************************/
911
912 constant_classref *class_get_self_classref(classinfo *cls)
913 {
914         /* XXX this should be done in a faster way. Maybe always make */
915         /* the classref of index 0 a self reference.                  */
916         return class_get_classref(cls,cls->name);
917 }
918
919 /* class_get_classref_multiarray_of ********************************************
920
921    Returns an array type reference with the given dimension and element class
922    reference.
923
924    IN:
925        dim..............the requested dimension
926                             dim must be in [1;255]. This is NOT checked!
927            ref..............the component class reference
928
929    RETURN VALUE:
930        a pointer to the class reference for the array type
931
932    NOTE:
933        The referer of `ref` is used as the referer for the new classref.
934
935 *******************************************************************************/
936
937 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
938 {
939     s4 namelen;
940     char *namebuf;
941         s4 dumpsize;
942         constant_classref *cr;
943
944         assert(ref);
945         assert(dim >= 1 && dim <= 255);
946
947         dumpsize = dump_size();
948
949     /* Assemble the array class name */
950     namelen = ref->name->blength;
951     
952     if (ref->name->text[0] == '[') {
953         /* the element is itself an array */
954         namebuf = DMNEW(char, namelen + dim);
955         memcpy(namebuf + dim, ref->name->text, namelen);
956         namelen += dim;
957     }
958     else {
959         /* the element is a non-array class */
960         namebuf = DMNEW(char, namelen + 2 + dim);
961         namebuf[dim] = 'L';
962         memcpy(namebuf + dim + 1, ref->name->text, namelen);
963         namelen += (2 + dim);
964         namebuf[namelen - 1] = ';';
965     }
966         memset(namebuf, '[', dim);
967
968     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
969
970         dump_release(dumpsize);
971
972         return cr;
973 }
974
975
976 /* class_get_classref_component_of *********************************************
977
978    Returns the component classref of a given array type reference
979
980    IN:
981        ref..............the array type reference
982
983    RETURN VALUE:
984        a reference to the component class, or
985            NULL if `ref` is not an object array type reference
986
987    NOTE:
988        The referer of `ref` is used as the referer for the new classref.
989
990 *******************************************************************************/
991
992 constant_classref *class_get_classref_component_of(constant_classref *ref)
993 {
994         s4 namelen;
995         char *name;
996         
997         assert(ref);
998
999         name = ref->name->text;
1000         if (*name++ != '[')
1001                 return NULL;
1002         
1003         namelen = ref->name->blength - 1;
1004         if (*name == 'L') {
1005                 name++;
1006                 namelen -= 2;
1007         }
1008         else if (*name != '[') {
1009                 return NULL;
1010         }
1011
1012     return class_get_classref(ref->referer, utf_new(name, namelen));
1013 }
1014
1015
1016 /* class_findmethod ************************************************************
1017         
1018    Searches a 'classinfo' structure for a method having the given name
1019    and descriptor. If descriptor is NULL, it is ignored.
1020
1021 *******************************************************************************/
1022
1023 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1024 {
1025         methodinfo *m;
1026         s4          i;
1027
1028         for (i = 0; i < c->methodscount; i++) {
1029                 m = &(c->methods[i]);
1030
1031                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1032                         return m;
1033         }
1034
1035         return NULL;
1036 }
1037
1038
1039 /* class_resolvemethod *********************************************************
1040         
1041    Searches a class and it's super classes for a method.
1042
1043    Superinterfaces are *not* searched.
1044
1045 *******************************************************************************/
1046
1047 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1048 {
1049         methodinfo *m;
1050
1051         while (c) {
1052                 m = class_findmethod(c, name, desc);
1053
1054                 if (m)
1055                         return m;
1056
1057                 /* JVM Specification bug: 
1058
1059                    It is important NOT to resolve special <init> and <clinit>
1060                    methods to super classes or interfaces; yet, this is not
1061                    explicited in the specification.  Section 5.4.3.3 should be
1062                    updated appropriately.  */
1063
1064                 if (name == utf_init || name == utf_clinit)
1065                         return NULL;
1066
1067                 c = c->super.cls;
1068         }
1069
1070         return NULL;
1071 }
1072
1073
1074 /* class_resolveinterfacemethod_intern *****************************************
1075
1076    Internally used helper function. Do not use this directly.
1077
1078 *******************************************************************************/
1079
1080 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1081                                                                                                            utf *name, utf *desc)
1082 {
1083         methodinfo *m;
1084         s4          i;
1085
1086         /* try to find the method in the class */
1087
1088         m = class_findmethod(c, name, desc);
1089
1090         if (m != NULL)
1091                 return m;
1092
1093         /* no method found? try the superinterfaces */
1094
1095         for (i = 0; i < c->interfacescount; i++) {
1096                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1097                                                                                                         name, desc);
1098
1099                 if (m != NULL)
1100                         return m;
1101         }
1102
1103         /* no method found */
1104
1105         return NULL;
1106 }
1107
1108
1109 /* class_resolveclassmethod ****************************************************
1110         
1111    Resolves a reference from REFERER to a method with NAME and DESC in
1112    class C.
1113
1114    If the method cannot be resolved the return value is NULL. If
1115    EXCEPT is true *exceptionptr is set, too.
1116
1117 *******************************************************************************/
1118
1119 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1120                                                                          classinfo *referer, bool throwexception)
1121 {
1122         classinfo  *cls;
1123         methodinfo *m;
1124         s4          i;
1125
1126 /*      if (c->flags & ACC_INTERFACE) { */
1127 /*              if (throwexception) */
1128 /*                      *exceptionptr = */
1129 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1130 /*              return NULL; */
1131 /*      } */
1132
1133         /* try class c and its superclasses */
1134
1135         cls = c;
1136
1137         m = class_resolvemethod(cls, name, desc);
1138
1139         if (m != NULL)
1140                 goto found;
1141
1142         /* try the superinterfaces */
1143
1144         for (i = 0; i < c->interfacescount; i++) {
1145                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1146                                                                                                 name, desc);
1147
1148                 if (m != NULL)
1149                         goto found;
1150         }
1151         
1152         if (throwexception)
1153                 exceptions_throw_nosuchmethoderror(c, name, desc);
1154
1155         return NULL;
1156
1157  found:
1158         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1159                 if (throwexception)
1160                         exceptions_throw_abstractmethoderror();
1161
1162                 return NULL;
1163         }
1164
1165         /* XXX check access rights */
1166
1167         return m;
1168 }
1169
1170
1171 /* class_resolveinterfacemethod ************************************************
1172
1173    Resolves a reference from REFERER to a method with NAME and DESC in
1174    interface C.
1175
1176    If the method cannot be resolved the return value is NULL. If
1177    EXCEPT is true *exceptionptr is set, too.
1178
1179 *******************************************************************************/
1180
1181 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1182                                                                                  classinfo *referer, bool throwexception)
1183 {
1184         methodinfo *mi;
1185
1186         if (!(c->flags & ACC_INTERFACE)) {
1187                 if (throwexception)
1188                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1189
1190                 return NULL;
1191         }
1192
1193         mi = class_resolveinterfacemethod_intern(c, name, desc);
1194
1195         if (mi != NULL)
1196                 return mi;
1197
1198         /* try class java.lang.Object */
1199
1200         mi = class_findmethod(class_java_lang_Object, name, desc);
1201
1202         if (mi != NULL)
1203                 return mi;
1204
1205         if (throwexception)
1206                 exceptions_throw_nosuchmethoderror(c, name, desc);
1207
1208         return NULL;
1209 }
1210
1211
1212 /* class_findfield *************************************************************
1213         
1214    Searches for field with specified name and type in a classinfo
1215    structure. If no such field is found NULL is returned.
1216
1217 *******************************************************************************/
1218
1219 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1220 {
1221         s4 i;
1222
1223         for (i = 0; i < c->fieldscount; i++)
1224                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1225                         return &(c->fields[i]);
1226
1227         if (c->super.cls)
1228                 return class_findfield(c->super.cls, name, desc);
1229
1230         return NULL;
1231 }
1232
1233
1234 /* class_findfield_approx ******************************************************
1235         
1236    Searches in 'classinfo'-structure for a field with the specified
1237    name.
1238
1239 *******************************************************************************/
1240  
1241 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1242 {
1243         s4 i;
1244
1245         /* get field index */
1246
1247         i = class_findfield_index_by_name(c, name);
1248
1249         /* field was not found, return */
1250
1251         if (i == -1)
1252                 return NULL;
1253
1254         /* return field address */
1255
1256         return &(c->fields[i]);
1257 }
1258
1259
1260 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1261 {
1262         s4 i;
1263
1264         for (i = 0; i < c->fieldscount; i++) {
1265                 /* compare field names */
1266
1267                 if ((c->fields[i].name == name))
1268                         return i;
1269         }
1270
1271         /* field was not found, raise exception */      
1272
1273         exceptions_throw_nosuchfielderror(c, name);
1274
1275         return -1;
1276 }
1277
1278
1279 /****************** Function: class_resolvefield_int ***************************
1280
1281     This is an internally used helper function. Do not use this directly.
1282
1283         Tries to resolve a field having the given name and type.
1284     If the field cannot be resolved, NULL is returned.
1285
1286 *******************************************************************************/
1287
1288 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1289 {
1290         fieldinfo *fi;
1291         s4         i;
1292
1293         /* search for field in class c */
1294
1295         for (i = 0; i < c->fieldscount; i++) { 
1296                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1297                         return &(c->fields[i]);
1298                 }
1299     }
1300
1301         /* try superinterfaces recursively */
1302
1303         for (i = 0; i < c->interfacescount; i++) {
1304                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1305                 if (fi)
1306                         return fi;
1307         }
1308
1309         /* try superclass */
1310
1311         if (c->super.cls)
1312                 return class_resolvefield_int(c->super.cls, name, desc);
1313
1314         /* not found */
1315
1316         return NULL;
1317 }
1318
1319
1320 /********************* Function: class_resolvefield ***************************
1321         
1322         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1323
1324     If the field cannot be resolved the return value is NULL. If EXCEPT is
1325     true *exceptionptr is set, too.
1326
1327 *******************************************************************************/
1328
1329 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1330                                                           classinfo *referer, bool throwexception)
1331 {
1332         fieldinfo *fi;
1333
1334         fi = class_resolvefield_int(c, name, desc);
1335
1336         if (!fi) {
1337                 if (throwexception)
1338                         exceptions_throw_nosuchfielderror(c, name);
1339
1340                 return NULL;
1341         }
1342
1343         /* XXX check access rights */
1344
1345         return fi;
1346 }
1347
1348
1349 /* class_issubclass ************************************************************
1350
1351    Checks if sub is a descendant of super.
1352         
1353 *******************************************************************************/
1354
1355 bool class_issubclass(classinfo *sub, classinfo *super)
1356 {
1357         for (;;) {
1358                 if (!sub)
1359                         return false;
1360
1361                 if (sub == super)
1362                         return true;
1363
1364                 sub = sub->super.cls;
1365         }
1366 }
1367
1368
1369 /* class_printflags ************************************************************
1370
1371    Prints flags of a class.
1372
1373 *******************************************************************************/
1374
1375 #if !defined(NDEBUG)
1376 void class_printflags(classinfo *c)
1377 {
1378         if (c == NULL) {
1379                 printf("NULL");
1380                 return;
1381         }
1382
1383         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1384         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1385         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1386         if (c->flags & ACC_STATIC)       printf(" STATIC");
1387         if (c->flags & ACC_FINAL)        printf(" FINAL");
1388         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1389         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1390         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1391         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1392         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1393         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1394 }
1395 #endif
1396
1397
1398 /* class_print *****************************************************************
1399
1400    Prints classname plus flags.
1401
1402 *******************************************************************************/
1403
1404 #if !defined(NDEBUG)
1405 void class_print(classinfo *c)
1406 {
1407         if (c == NULL) {
1408                 printf("NULL");
1409                 return;
1410         }
1411
1412         utf_display_printable_ascii(c->name);
1413         class_printflags(c);
1414 }
1415 #endif
1416
1417
1418 /* class_classref_print ********************************************************
1419
1420    Prints classname plus referer class.
1421
1422 *******************************************************************************/
1423
1424 #if !defined(NDEBUG)
1425 void class_classref_print(constant_classref *cr)
1426 {
1427         if (cr == NULL) {
1428                 printf("NULL");
1429                 return;
1430         }
1431
1432         utf_display_printable_ascii(cr->name);
1433         printf("(ref.by ");
1434         if (cr->referer)
1435                 class_print(cr->referer);
1436         else
1437                 printf("NULL");
1438         printf(")");
1439 }
1440 #endif
1441
1442
1443 /* class_println ***************************************************************
1444
1445    Prints classname plus flags and new line.
1446
1447 *******************************************************************************/
1448
1449 #if !defined(NDEBUG)
1450 void class_println(classinfo *c)
1451 {
1452         class_print(c);
1453         printf("\n");
1454 }
1455 #endif
1456
1457
1458 /* class_classref_println ******************************************************
1459
1460    Prints classname plus referer class and new line.
1461
1462 *******************************************************************************/
1463
1464 #if !defined(NDEBUG)
1465 void class_classref_println(constant_classref *cr)
1466 {
1467         class_classref_print(cr);
1468         printf("\n");
1469 }
1470 #endif
1471
1472
1473 /* class_classref_or_classinfo_print *******************************************
1474
1475    Prints classname plus referer class.
1476
1477 *******************************************************************************/
1478
1479 #if !defined(NDEBUG)
1480 void class_classref_or_classinfo_print(classref_or_classinfo c)
1481 {
1482         if (c.any == NULL) {
1483                 printf("(classref_or_classinfo) NULL");
1484                 return;
1485         }
1486         if (IS_CLASSREF(c))
1487                 class_classref_print(c.ref);
1488         else
1489                 class_print(c.cls);
1490 }
1491 #endif
1492
1493
1494 /* class_classref_or_classinfo_println *****************************************
1495
1496    Prints classname plus referer class and a newline.
1497
1498 *******************************************************************************/
1499
1500 void class_classref_or_classinfo_println(classref_or_classinfo c)
1501 {
1502         class_classref_or_classinfo_println(c);
1503         printf("\n");
1504 }
1505
1506
1507 /* class_showconstantpool ******************************************************
1508
1509    Dump the constant pool of the given class to stdout.
1510
1511 *******************************************************************************/
1512
1513 #if !defined(NDEBUG)
1514 void class_showconstantpool (classinfo *c) 
1515 {
1516         u4 i;
1517         voidptr e;
1518
1519         printf ("---- dump of constant pool ----\n");
1520
1521         for (i=0; i<c->cpcount; i++) {
1522                 printf ("#%d:  ", (int) i);
1523                 
1524                 e = c -> cpinfos [i];
1525                 if (e) {
1526                         
1527                         switch (c -> cptags [i]) {
1528                         case CONSTANT_Class:
1529                                 printf ("Classreference -> ");
1530                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1531                                 break;
1532                         case CONSTANT_Fieldref:
1533                                 printf ("Fieldref -> ");
1534                                 field_fieldref_print((constant_FMIref *) e);
1535                                 break;
1536                         case CONSTANT_Methodref:
1537                                 printf ("Methodref -> ");
1538                                 method_methodref_print((constant_FMIref *) e);
1539                                 break;
1540                         case CONSTANT_InterfaceMethodref:
1541                                 printf ("InterfaceMethod -> ");
1542                                 method_methodref_print((constant_FMIref *) e);
1543                                 break;
1544                         case CONSTANT_String:
1545                                 printf ("String -> ");
1546                                 utf_display_printable_ascii (e);
1547                                 break;
1548                         case CONSTANT_Integer:
1549                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1550                                 break;
1551                         case CONSTANT_Float:
1552                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1553                                 break;
1554                         case CONSTANT_Double:
1555                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1556                                 break;
1557                         case CONSTANT_Long:
1558                                 {
1559                                         u8 v = ((constant_long*)e) -> value;
1560 #if U8_AVAILABLE
1561                                         printf ("Long -> %ld", (long int) v);
1562 #else
1563                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1564                                                         (long int) v.high, (long int) v.low);
1565 #endif 
1566                                 }
1567                                 break;
1568                         case CONSTANT_NameAndType:
1569                                 {
1570                                         constant_nameandtype *cnt = e;
1571                                         printf ("NameAndType: ");
1572                                         utf_display_printable_ascii (cnt->name);
1573                                         printf (" ");
1574                                         utf_display_printable_ascii (cnt->descriptor);
1575                                 }
1576                                 break;
1577                         case CONSTANT_Utf8:
1578                                 printf ("Utf8 -> ");
1579                                 utf_display_printable_ascii (e);
1580                                 break;
1581                         default: 
1582                                 log_text("Invalid type of ConstantPool-Entry");
1583                                 assert(0);
1584                         }
1585                 }
1586
1587                 printf ("\n");
1588         }
1589 }
1590 #endif /* !defined(NDEBUG) */
1591
1592
1593 /* class_showmethods ***********************************************************
1594
1595    Dump info about the fields and methods of the given class to stdout.
1596
1597 *******************************************************************************/
1598
1599 #if !defined(NDEBUG)
1600 void class_showmethods (classinfo *c)
1601 {
1602         s4 i;
1603         
1604         printf("--------- Fields and Methods ----------------\n");
1605         printf("Flags: ");
1606         class_printflags(c);
1607         printf("\n");
1608
1609         printf("This: ");
1610         utf_display_printable_ascii(c->name);
1611         printf("\n");
1612
1613         if (c->super.cls) {
1614                 printf("Super: ");
1615                 utf_display_printable_ascii(c->super.cls->name);
1616                 printf ("\n");
1617         }
1618
1619         printf("Index: %d\n", c->index);
1620         
1621         printf("Interfaces:\n");        
1622         for (i = 0; i < c->interfacescount; i++) {
1623                 printf("   ");
1624                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1625                 printf (" (%d)\n", c->interfaces[i].cls->index);
1626         }
1627
1628         printf("Fields:\n");
1629         for (i = 0; i < c->fieldscount; i++)
1630                 field_println(&(c->fields[i]));
1631
1632         printf("Methods:\n");
1633         for (i = 0; i < c->methodscount; i++) {
1634                 methodinfo *m = &(c->methods[i]);
1635
1636                 if (!(m->flags & ACC_STATIC))
1637                         printf("vftblindex: %d   ", m->vftblindex);
1638
1639                 method_println(m);
1640         }
1641
1642         printf ("Virtual function table:\n");
1643         for (i = 0; i < c->vftbl->vftbllength; i++)
1644                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1645 }
1646 #endif /* !defined(NDEBUG) */
1647
1648
1649 /*
1650  * These are local overrides for various environment variables in Emacs.
1651  * Please do not remove this and leave it at the end of the file, where
1652  * Emacs will automagically detect them.
1653  * ---------------------------------------------------------------------
1654  * Local variables:
1655  * mode: c
1656  * indent-tabs-mode: t
1657  * c-basic-offset: 4
1658  * tab-width: 4
1659  * End:
1660  * vim:noexpandtab:sw=4:ts=4:
1661  */