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