* don't include "md.h", not needed
[cacao.git] / src / vm / class.c
1 /* src/vm/class.c - class related functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Mark Probst
30             Andreas Krall
31             Christian Thalinger
32
33    $Id: class.c 2743 2005-06-20 11:54:06Z edwin $
34
35 */
36
37 #include <assert.h>
38 #include <string.h>
39
40 #include "vm/global.h"
41 #include "mm/memory.h"
42
43 #if defined(USE_THREADS)
44 # if defined(NATIVE_THREADS)
45 #  include "threads/native/threads.h"
46 # else
47 #  include "threads/green/threads.h"
48 #  include "threads/green/locks.h"
49 # endif
50 #endif
51
52 #include "toolbox/logging.h"
53 #include "vm/class.h"
54 #include "vm/classcache.h"
55 #include "vm/exceptions.h"
56 #include "vm/loader.h"
57 #include "vm/options.h"
58 #include "vm/resolve.h"
59 #include "vm/statistics.h"
60 #include "vm/tables.h"
61 #include "vm/utf8.h"
62
63
64 /******************************************************************************/
65 /* DEBUG HELPERS                                                              */
66 /******************************************************************************/
67
68 #ifndef NDEBUG
69 #define CLASS_DEBUG
70 #endif
71
72 #ifdef CLASS_DEBUG
73 #define CLASS_ASSERT(cond)  assert(cond)
74 #else
75 #define CLASS_ASSERT(cond)
76 #endif
77
78
79 /* global variables ***********************************************************/
80
81 list unlinkedclasses;                   /* this is only used for eager class  */
82                                         /* loading                            */
83
84
85 /* frequently used classes ****************************************************/
86
87 /* important system classes */
88
89 classinfo *class_java_lang_Object = NULL;
90 classinfo *class_java_lang_Class = NULL;
91 classinfo *class_java_lang_ClassLoader = NULL;
92 classinfo *class_java_lang_Cloneable = NULL;
93 classinfo *class_java_lang_SecurityManager = NULL;
94 classinfo *class_java_lang_String = NULL;
95 classinfo *class_java_lang_System = NULL;
96 classinfo *class_java_lang_ThreadGroup = NULL;
97 classinfo *class_java_io_Serializable = NULL;
98
99
100 /* system exception classes required in cacao */
101
102 classinfo *class_java_lang_Throwable = NULL;
103 classinfo *class_java_lang_VMThrowable = NULL;
104 classinfo *class_java_lang_Error = NULL;
105 classinfo *class_java_lang_NoClassDefFoundError = NULL;
106 classinfo *class_java_lang_OutOfMemoryError = NULL;
107
108 classinfo *class_java_lang_Exception = NULL;
109 classinfo *class_java_lang_ClassNotFoundException = NULL;
110
111 classinfo *class_java_lang_Void = NULL;
112 classinfo *class_java_lang_Boolean = NULL;
113 classinfo *class_java_lang_Byte = NULL;
114 classinfo *class_java_lang_Character = NULL;
115 classinfo *class_java_lang_Short = NULL;
116 classinfo *class_java_lang_Integer = NULL;
117 classinfo *class_java_lang_Long = NULL;
118 classinfo *class_java_lang_Float = NULL;
119 classinfo *class_java_lang_Double = NULL;
120
121
122 /* some classes which may be used more often */
123
124 classinfo *class_java_lang_StackTraceElement = NULL;
125 classinfo *class_java_lang_reflect_Constructor = NULL;
126 classinfo *class_java_lang_reflect_Field = NULL;
127 classinfo *class_java_lang_reflect_Method = NULL;
128 classinfo *class_java_security_PrivilegedAction = NULL;
129 classinfo *class_java_util_Vector = NULL;
130
131 classinfo *arrayclass_java_lang_Object = NULL;
132
133
134 /* pseudo classes for the typechecker */
135
136 classinfo *pseudo_class_Arraystub = NULL;
137 classinfo *pseudo_class_Null = NULL;
138 classinfo *pseudo_class_New = NULL;
139
140 /* class_set_packagename *******************************************************
141
142    Derive the package name from the class name and store it in the struct.
143
144 *******************************************************************************/
145
146 void class_set_packagename(classinfo *c)
147 {
148         if (c->name->text[0] == '[') {
149                 /* Array classes are not loaded from classfiles. */
150                 c->packagename = array_packagename;
151         } 
152         else {
153                 /* Find the package name */
154                 /* Classes in the unnamed package keep packagename == NULL. */
155                 char *p = UTF_END(c->name) - 1;
156                 char *start = c->name->text;
157                 for (;p > start; --p) {
158                         if (*p == '/') {
159                                 c->packagename = utf_new(start, p - start);
160                                 break;
161                         }
162                 }
163         }
164 }
165
166 /* class_create_classinfo ******************************************************
167
168    Create a new classinfo struct. The class name is set to the given utf *,
169    most other fields are initialized to zero.
170
171    Note: classname may be NULL. In this case a not-yet-named classinfo is
172          created. The name must be filled in later and class_set_packagename
173                  must be called after that.
174
175 *******************************************************************************/
176
177 classinfo *class_create_classinfo(utf *classname)
178 {
179         classinfo *c;
180
181 #if defined(STATISTICS)
182         if (opt_stat)
183                 count_class_infos += sizeof(classinfo);
184 #endif
185
186         /* we use a safe name for temporarily unnamed classes */
187         if (!classname)
188                 classname = utf_not_named_yet;
189
190         if (initverbose)
191                 log_message_utf("Creating class: ", classname);
192
193         c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
194         /*c=NEW(classinfo);*/
195         c->vmClass = 0;
196         c->flags = 0;
197         c->name = classname;
198         c->packagename = NULL;
199         c->cpcount = 0;
200         c->cptags = NULL;
201         c->cpinfos = NULL;
202         c->classrefs = NULL;
203         c->extclassrefs = NULL;
204         c->classrefcount = 0;
205         c->parseddescs = NULL;
206         c->parseddescsize = 0;
207         c->super.any = NULL;
208         c->sub = NULL;
209         c->nextsub = NULL;
210         c->interfacescount = 0;
211         c->interfaces = NULL;
212         c->fieldscount = 0;
213         c->fields = NULL;
214         c->methodscount = 0;
215         c->methods = NULL;
216         c->linked = false;
217         c->loaded = false;
218         c->index = 0;
219         c->instancesize = 0;
220         c->header.vftbl = NULL;
221         c->innerclasscount = 0;
222         c->innerclass = NULL;
223         c->vftbl = NULL;
224         c->initialized = false;
225         c->initializing = false;
226         c->classvftbl = false;
227     c->classUsed = 0;
228     c->impldBy = NULL;
229         c->classloader = NULL;
230         c->sourcefile = NULL;
231         
232         if (classname != utf_not_named_yet) {
233                 class_set_packagename(c);
234         }
235
236 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
237         initObjectLock(&c->header);
238 #endif
239
240         return c;
241 }
242
243 /* class_freepool **************************************************************
244
245         Frees all resources used by this classes Constant Pool.
246
247 *******************************************************************************/
248
249 static void class_freecpool(classinfo *c)
250 {
251         u4 idx;
252         u4 tag;
253         voidptr info;
254         
255         if (c->cptags && c->cpinfos) {
256                 for (idx = 0; idx < c->cpcount; idx++) {
257                         tag = c->cptags[idx];
258                         info = c->cpinfos[idx];
259                 
260                         if (info != NULL) {
261                                 switch (tag) {
262                                 case CONSTANT_Fieldref:
263                                 case CONSTANT_Methodref:
264                                 case CONSTANT_InterfaceMethodref:
265                                         FREE(info, constant_FMIref);
266                                         break;
267                                 case CONSTANT_Integer:
268                                         FREE(info, constant_integer);
269                                         break;
270                                 case CONSTANT_Float:
271                                         FREE(info, constant_float);
272                                         break;
273                                 case CONSTANT_Long:
274                                         FREE(info, constant_long);
275                                         break;
276                                 case CONSTANT_Double:
277                                         FREE(info, constant_double);
278                                         break;
279                                 case CONSTANT_NameAndType:
280                                         FREE(info, constant_nameandtype);
281                                         break;
282                                 }
283                         }
284                 }
285         }
286
287         if (c->cptags)
288                 MFREE(c->cptags, u1, c->cpcount);
289
290         if (c->cpinfos)
291                 MFREE(c->cpinfos, voidptr, c->cpcount);
292 }
293
294
295 /* class_getconstant ***********************************************************
296
297    Retrieves the value at position 'pos' of the constantpool of a
298    class. If the type of the value is other than 'ctype', an error is
299    thrown.
300
301 *******************************************************************************/
302
303 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
304 {
305         /* check index and type of constantpool entry */
306         /* (pos == 0 is caught by type comparison) */
307
308         if (pos >= c->cpcount || c->cptags[pos] != ctype) {
309                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
310                 return NULL;
311         }
312
313         return c->cpinfos[pos];
314 }
315
316
317 /* innerclass_getconstant ******************************************************
318
319    Like class_getconstant, but if cptags is ZERO, null is returned.
320         
321 *******************************************************************************/
322
323 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
324 {
325         /* invalid position in constantpool */
326         if (pos >= c->cpcount) {
327                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
328                 return NULL;
329         }
330
331         /* constantpool entry of type 0 */      
332         if (!c->cptags[pos])
333                 return NULL;
334
335         /* check type of constantpool entry */
336         if (c->cptags[pos] != ctype) {
337                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
338                 return NULL;
339         }
340                 
341         return c->cpinfos[pos];
342 }
343
344
345 /* class_free ******************************************************************
346
347    Frees all resources used by the class.
348
349 *******************************************************************************/
350
351 void class_free(classinfo *c)
352 {
353         s4 i;
354         vftbl_t *v;
355                 
356         class_freecpool(c);
357
358         if (c->interfaces)
359                 MFREE(c->interfaces, classinfo*, c->interfacescount);
360
361         if (c->fields) {
362                 for (i = 0; i < c->fieldscount; i++)
363                         field_free(&(c->fields[i]));
364 /*      MFREE(c->fields, fieldinfo, c->fieldscount); */
365         }
366         
367         if (c->methods) {
368                 for (i = 0; i < c->methodscount; i++)
369                         method_free(&(c->methods[i]));
370                 MFREE(c->methods, methodinfo, c->methodscount);
371         }
372
373         if ((v = c->vftbl) != NULL) {
374                 if (v->arraydesc)
375                         mem_free(v->arraydesc,sizeof(arraydescriptor));
376                 
377                 for (i = 0; i < v->interfacetablelength; i++) {
378                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
379                 }
380                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
381
382                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
383                     sizeof(methodptr*) * (v->interfacetablelength -
384                                          (v->interfacetablelength > 0));
385                 v = (vftbl_t*) (((methodptr*) v) -
386                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
387                 mem_free(v, i);
388         }
389
390         if (c->innerclass)
391                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
392
393         /*      if (c->classvftbl)
394                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
395         
396 /*      GCFREE(c); */
397 }
398
399
400 /* get_array_class *************************************************************
401
402    Returns the array class with the given name for the given
403    classloader, or NULL if an exception occurred.
404
405    Note: This function does eager loading. 
406
407 *******************************************************************************/
408
409 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
410                                                                                         java_objectheader *defloader,bool link)
411 {
412         classinfo *c;
413         
414         /* lookup this class in the classcache */
415         c = classcache_lookup(initloader,name);
416         if (!c)
417                 c = classcache_lookup_defined(defloader,name);
418
419         if (!c) {
420                 /* we have to create it */
421                 c = class_create_classinfo(name);
422                 c = load_newly_created_array(c,initloader);
423                 if (c == NULL)
424                         return NULL;
425         }
426
427         CLASS_ASSERT(c);
428         CLASS_ASSERT(c->loaded);
429         CLASS_ASSERT(c->classloader == defloader);
430
431         if (link && !c->linked)
432                 if (!link_class(c))
433                         return NULL;
434
435         CLASS_ASSERT(!link || c->linked);
436
437         return c;
438 }
439
440
441 /* class_array_of **************************************************************
442
443    Returns an array class with the given component class. The array
444    class is dynamically created if neccessary.
445
446 *******************************************************************************/
447
448 classinfo *class_array_of(classinfo *component, bool link)
449 {
450     s4 namelen;
451     char *namebuf;
452
453     /* Assemble the array class name */
454     namelen = component->name->blength;
455     
456     if (component->name->text[0] == '[') {
457         /* the component is itself an array */
458         namebuf = DMNEW(char, namelen + 1);
459         namebuf[0] = '[';
460         MCOPY(namebuf + 1, component->name->text, char, namelen);
461         namelen++;
462
463     } else {
464         /* the component is a non-array class */
465         namebuf = DMNEW(char, namelen + 3);
466         namebuf[0] = '[';
467         namebuf[1] = 'L';
468         MCOPY(namebuf + 2, component->name->text, char, namelen);
469         namebuf[2 + namelen] = ';';
470         namelen += 3;
471     }
472
473         return get_array_class(utf_new(namebuf, namelen),
474                                                    component->classloader,
475                                                    component->classloader,
476                                                    link);
477 }
478
479
480 /* class_multiarray_of *********************************************************
481
482    Returns an array class with the given dimension and element class.
483    The array class is dynamically created if neccessary.
484
485 *******************************************************************************/
486
487 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
488 {
489     s4 namelen;
490     char *namebuf;
491
492         if (dim < 1) {
493                 log_text("Invalid array dimension requested");
494                 assert(0);
495         }
496
497     /* Assemble the array class name */
498     namelen = element->name->blength;
499     
500     if (element->name->text[0] == '[') {
501         /* the element is itself an array */
502         namebuf = DMNEW(char, namelen + dim);
503         memcpy(namebuf + dim, element->name->text, namelen);
504         namelen += dim;
505     }
506     else {
507         /* the element is a non-array class */
508         namebuf = DMNEW(char, namelen + 2 + dim);
509         namebuf[dim] = 'L';
510         memcpy(namebuf + dim + 1, element->name->text, namelen);
511         namelen += (2 + dim);
512         namebuf[namelen - 1] = ';';
513     }
514         memset(namebuf, '[', dim);
515
516         return get_array_class(utf_new(namebuf, namelen),
517                                                    element->classloader,
518                                                    element->classloader,
519                                                    link);
520 }
521
522
523 /* class_lookup_classref *******************************************************
524
525    Looks up the constant_classref for a given classname in the classref
526    tables of a class.
527
528    IN:
529        cls..............the class containing the reference
530            name.............the name of the class refered to
531
532     RETURN VALUE:
533            a pointer to a constant_classref, or 
534            NULL if the reference was not found
535    
536 *******************************************************************************/
537
538 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
539 {
540         constant_classref *ref;
541         extra_classref *xref;
542         int count;
543
544         CLASS_ASSERT(cls);
545         CLASS_ASSERT(name);
546         CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
547         
548         /* first search the main classref table */
549         count = cls->classrefcount;
550         ref = cls->classrefs;
551         for (; count; --count, ++ref)
552                 if (ref->name == name)
553                         return ref;
554
555         /* next try the list of extra classrefs */
556         for (xref = cls->extclassrefs; xref; xref = xref->next) {
557                 if (xref->classref.name == name)
558                         return &(xref->classref);
559         }
560
561         /* not found */
562         return NULL;
563 }
564
565
566 /* class_get_classref **********************************************************
567
568    Returns the constant_classref for a given classname.
569
570    IN:
571        cls..............the class containing the reference
572            name.............the name of the class refered to
573
574    RETURN VALUE:
575        a pointer to a constant_classref (never NULL)
576
577    NOTE:
578        The given name is not checked for validity!
579    
580 *******************************************************************************/
581
582 constant_classref *class_get_classref(classinfo *cls, utf *name)
583 {
584         constant_classref *ref;
585         extra_classref *xref;
586
587         CLASS_ASSERT(cls);
588         CLASS_ASSERT(name);
589
590         ref = class_lookup_classref(cls,name);
591         if (ref)
592                 return ref;
593
594         xref = NEW(extra_classref);
595         CLASSREF_INIT(xref->classref,cls,name);
596
597         xref->next = cls->extclassrefs;
598         cls->extclassrefs = xref;
599
600         return &(xref->classref);
601 }
602
603
604 /* class_get_self_classref *****************************************************
605
606    Returns the constant_classref to the class itself.
607
608    IN:
609        cls..............the class containing the reference
610
611    RETURN VALUE:
612        a pointer to a constant_classref (never NULL)
613
614 *******************************************************************************/
615
616 constant_classref *class_get_self_classref(classinfo *cls)
617 {
618         /* XXX this should be done in a faster way. Maybe always make */
619         /* the classref of index 0 a self reference.                  */
620         return class_get_classref(cls,cls->name);
621 }
622
623 /* class_get_classref_multiarray_of ********************************************
624
625    Returns an array type reference with the given dimension and element class
626    reference.
627
628    IN:
629        dim..............the requested dimension
630                             dim must be in [1;255]. This is NOT checked!
631            ref..............the component class reference
632
633    RETURN VALUE:
634        a pointer to the class reference for the array type
635
636    NOTE:
637        The referer of `ref` is used as the referer for the new classref.
638
639 *******************************************************************************/
640
641 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
642 {
643     s4 namelen;
644     char *namebuf;
645
646         CLASS_ASSERT(ref);
647         CLASS_ASSERT(dim >= 1 && dim <= 255);
648
649     /* Assemble the array class name */
650     namelen = ref->name->blength;
651     
652     if (ref->name->text[0] == '[') {
653         /* the element is itself an array */
654         namebuf = DMNEW(char, namelen + dim);
655         memcpy(namebuf + dim, ref->name->text, namelen);
656         namelen += dim;
657     }
658     else {
659         /* the element is a non-array class */
660         namebuf = DMNEW(char, namelen + 2 + dim);
661         namebuf[dim] = 'L';
662         memcpy(namebuf + dim + 1, ref->name->text, namelen);
663         namelen += (2 + dim);
664         namebuf[namelen - 1] = ';';
665     }
666         memset(namebuf, '[', dim);
667
668     return class_get_classref(ref->referer,utf_new(namebuf, namelen));
669 }
670
671 /* class_get_classref_component_of *********************************************
672
673    Returns the component classref of a given array type reference
674
675    IN:
676        ref..............the array type reference
677
678    RETURN VALUE:
679        a reference to the component class, or
680            NULL if `ref` is not an object array type reference
681
682    NOTE:
683        The referer of `ref` is used as the referer for the new classref.
684
685 *******************************************************************************/
686
687 constant_classref *class_get_classref_component_of(constant_classref *ref)
688 {
689         s4 namelen;
690         char *name;
691         
692         CLASS_ASSERT(ref);
693
694         name = ref->name->text;
695         if (*name++ != '[')
696                 return NULL;
697         
698         namelen = ref->name->blength - 1;
699         if (*name == 'L') {
700                 name++;
701                 namelen -= 2;
702         }
703         else if (*name != '[') {
704                 return NULL;
705         }
706
707     return class_get_classref(ref->referer, utf_new(name, namelen));
708 }
709
710
711 /*
712  * These are local overrides for various environment variables in Emacs.
713  * Please do not remove this and leave it at the end of the file, where
714  * Emacs will automagically detect them.
715  * ---------------------------------------------------------------------
716  * Local variables:
717  * mode: c
718  * indent-tabs-mode: t
719  * c-basic-offset: 4
720  * tab-width: 4
721  * End:
722  */