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