* moved ABI stuff into md-abi.h
[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 2523 2005-05-23 18:13:52Z 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 /* some classes which may be used more often */
122
123 classinfo *class_java_util_Vector = NULL;
124 classinfo *class_java_lang_reflect_Constructor = NULL;
125 classinfo *class_java_lang_reflect_Method = NULL;
126 classinfo *arrayclass_java_lang_Object=NULL;
127
128 /* pseudo classes for the typechecker */
129
130 classinfo *pseudo_class_Arraystub = NULL;
131 classinfo *pseudo_class_Null = NULL;
132 classinfo *pseudo_class_New = NULL;
133
134 /* class_set_packagename *******************************************************
135
136    Derive the package name from the class name and store it in the struct.
137
138 *******************************************************************************/
139
140 void class_set_packagename(classinfo *c)
141 {
142         if (c->name->text[0] == '[') {
143                 /* Array classes are not loaded from classfiles. */
144                 c->packagename = array_packagename;
145         } 
146         else {
147                 /* Find the package name */
148                 /* Classes in the unnamed package keep packagename == NULL. */
149                 char *p = utf_end(c->name) - 1;
150                 char *start = c->name->text;
151                 for (;p > start; --p) {
152                         if (*p == '/') {
153                                 c->packagename = utf_new(start, p - start);
154                                 break;
155                         }
156                 }
157         }
158 }
159
160 /* class_create_classinfo ******************************************************
161
162    Create a new classinfo struct. The class name is set to the given utf *,
163    most other fields are initialized to zero.
164
165    Note: classname may be NULL. In this case a not-yet-named classinfo is
166          created. The name must be filled in later and class_set_packagename
167                  must be called after that.
168
169 *******************************************************************************/
170
171 classinfo *class_create_classinfo(utf *classname)
172 {
173         classinfo *c;
174
175 #if defined(STATISTICS)
176         if (opt_stat)
177                 count_class_infos += sizeof(classinfo);
178 #endif
179
180         /* we use a safe name for temporarily unnamed classes */
181         if (!classname)
182                 classname = utf_not_named_yet;
183
184         if (initverbose)
185                 log_message_utf("Creating class: ", classname);
186
187         c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
188         /*c=NEW(classinfo);*/
189         c->vmClass = 0;
190         c->flags = 0;
191         c->name = classname;
192         c->packagename = NULL;
193         c->cpcount = 0;
194         c->cptags = NULL;
195         c->cpinfos = NULL;
196         c->classrefs = NULL;
197         c->extclassrefs = NULL;
198         c->classrefcount = 0;
199         c->parseddescs = NULL;
200         c->parseddescsize = 0;
201         c->super.any = NULL;
202         c->sub = NULL;
203         c->nextsub = NULL;
204         c->interfacescount = 0;
205         c->interfaces = NULL;
206         c->fieldscount = 0;
207         c->fields = NULL;
208         c->methodscount = 0;
209         c->methods = NULL;
210         c->linked = false;
211         c->loaded = false;
212         c->index = 0;
213         c->instancesize = 0;
214         c->header.vftbl = NULL;
215         c->innerclasscount = 0;
216         c->innerclass = NULL;
217         c->vftbl = NULL;
218         c->initialized = false;
219         c->initializing = false;
220         c->classvftbl = false;
221     c->classUsed = 0;
222     c->impldBy = NULL;
223         c->classloader = NULL;
224         c->sourcefile = NULL;
225         
226         if (classname != utf_not_named_yet) {
227                 class_set_packagename(c);
228         }
229
230 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
231         initObjectLock(&c->header);
232 #endif
233
234         return c;
235 }
236
237 /* class_freepool **************************************************************
238
239         Frees all resources used by this classes Constant Pool.
240
241 *******************************************************************************/
242
243 static void class_freecpool(classinfo *c)
244 {
245         u4 idx;
246         u4 tag;
247         voidptr info;
248         
249         if (c->cptags && c->cpinfos) {
250                 for (idx = 0; idx < c->cpcount; idx++) {
251                         tag = c->cptags[idx];
252                         info = c->cpinfos[idx];
253                 
254                         if (info != NULL) {
255                                 switch (tag) {
256                                 case CONSTANT_Fieldref:
257                                 case CONSTANT_Methodref:
258                                 case CONSTANT_InterfaceMethodref:
259                                         FREE(info, constant_FMIref);
260                                         break;
261                                 case CONSTANT_Integer:
262                                         FREE(info, constant_integer);
263                                         break;
264                                 case CONSTANT_Float:
265                                         FREE(info, constant_float);
266                                         break;
267                                 case CONSTANT_Long:
268                                         FREE(info, constant_long);
269                                         break;
270                                 case CONSTANT_Double:
271                                         FREE(info, constant_double);
272                                         break;
273                                 case CONSTANT_NameAndType:
274                                         FREE(info, constant_nameandtype);
275                                         break;
276                                 }
277                         }
278                 }
279         }
280
281         if (c->cptags)
282                 MFREE(c->cptags, u1, c->cpcount);
283
284         if (c->cpinfos)
285                 MFREE(c->cpinfos, voidptr, c->cpcount);
286 }
287
288
289 /* class_getconstant ***********************************************************
290
291    Retrieves the value at position 'pos' of the constantpool of a
292    class. If the type of the value is other than 'ctype', an error is
293    thrown.
294
295 *******************************************************************************/
296
297 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
298 {
299         /* check index and type of constantpool entry */
300         /* (pos == 0 is caught by type comparison) */
301
302         if (pos >= c->cpcount || c->cptags[pos] != ctype) {
303                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
304                 return NULL;
305         }
306
307         return c->cpinfos[pos];
308 }
309
310
311 /* innerclass_getconstant ******************************************************
312
313    Like class_getconstant, but if cptags is ZERO, null is returned.
314         
315 *******************************************************************************/
316
317 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
318 {
319         /* invalid position in constantpool */
320         if (pos >= c->cpcount) {
321                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
322                 return NULL;
323         }
324
325         /* constantpool entry of type 0 */      
326         if (!c->cptags[pos])
327                 return NULL;
328
329         /* check type of constantpool entry */
330         if (c->cptags[pos] != ctype) {
331                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
332                 return NULL;
333         }
334                 
335         return c->cpinfos[pos];
336 }
337
338
339 /* class_free ******************************************************************
340
341    Frees all resources used by the class.
342
343 *******************************************************************************/
344
345 void class_free(classinfo *c)
346 {
347         s4 i;
348         vftbl_t *v;
349                 
350         class_freecpool(c);
351
352         if (c->interfaces)
353                 MFREE(c->interfaces, classinfo*, c->interfacescount);
354
355         if (c->fields) {
356                 for (i = 0; i < c->fieldscount; i++)
357                         field_free(&(c->fields[i]));
358 /*      MFREE(c->fields, fieldinfo, c->fieldscount); */
359         }
360         
361         if (c->methods) {
362                 for (i = 0; i < c->methodscount; i++)
363                         method_free(&(c->methods[i]));
364                 MFREE(c->methods, methodinfo, c->methodscount);
365         }
366
367         if ((v = c->vftbl) != NULL) {
368                 if (v->arraydesc)
369                         mem_free(v->arraydesc,sizeof(arraydescriptor));
370                 
371                 for (i = 0; i < v->interfacetablelength; i++) {
372                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
373                 }
374                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
375
376                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
377                     sizeof(methodptr*) * (v->interfacetablelength -
378                                          (v->interfacetablelength > 0));
379                 v = (vftbl_t*) (((methodptr*) v) -
380                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
381                 mem_free(v, i);
382         }
383
384         if (c->innerclass)
385                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
386
387         /*      if (c->classvftbl)
388                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
389         
390 /*      GCFREE(c); */
391 }
392
393
394 /* get_array_class *************************************************************
395
396    Returns the array class with the given name for the given
397    classloader, or NULL if an exception occurred.
398
399    Note: This function does eager loading. 
400
401 *******************************************************************************/
402
403 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
404                                                                                         java_objectheader *defloader,bool link)
405 {
406         classinfo *c;
407         
408         /* lookup this class in the classcache */
409         c = classcache_lookup(initloader,name);
410         if (!c)
411                 c = classcache_lookup_defined(defloader,name);
412
413         if (!c) {
414                 /* we have to create it */
415                 c = class_create_classinfo(name);
416                 if (!load_newly_created_array(c,initloader))
417                         return NULL;
418         }
419
420         CLASS_ASSERT(c);
421         CLASS_ASSERT(c->loaded);
422         CLASS_ASSERT(c->classloader == defloader);
423
424         if (link && !c->linked)
425                 if (!link_class(c))
426                         return NULL;
427
428         CLASS_ASSERT(!link || c->linked);
429
430         return c;
431 }
432
433
434 /* class_array_of **************************************************************
435
436    Returns an array class with the given component class. The array
437    class is dynamically created if neccessary.
438
439 *******************************************************************************/
440
441 classinfo *class_array_of(classinfo *component, bool link)
442 {
443     s4 namelen;
444     char *namebuf;
445
446     /* Assemble the array class name */
447     namelen = component->name->blength;
448     
449     if (component->name->text[0] == '[') {
450         /* the component is itself an array */
451         namebuf = DMNEW(char, namelen + 1);
452         namebuf[0] = '[';
453         MCOPY(namebuf + 1, component->name->text, char, namelen);
454         namelen++;
455
456     } else {
457         /* the component is a non-array class */
458         namebuf = DMNEW(char, namelen + 3);
459         namebuf[0] = '[';
460         namebuf[1] = 'L';
461         MCOPY(namebuf + 2, component->name->text, char, namelen);
462         namebuf[2 + namelen] = ';';
463         namelen += 3;
464     }
465
466         return get_array_class(utf_new(namebuf, namelen),
467                                                    component->classloader,
468                                                    component->classloader,
469                                                    link);
470 }
471
472
473 /* class_multiarray_of *********************************************************
474
475    Returns an array class with the given dimension and element class.
476    The array class is dynamically created if neccessary.
477
478 *******************************************************************************/
479
480 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
481 {
482     s4 namelen;
483     char *namebuf;
484
485         if (dim < 1) {
486                 log_text("Invalid array dimension requested");
487                 assert(0);
488         }
489
490     /* Assemble the array class name */
491     namelen = element->name->blength;
492     
493     if (element->name->text[0] == '[') {
494         /* the element is itself an array */
495         namebuf = DMNEW(char, namelen + dim);
496         memcpy(namebuf + dim, element->name->text, namelen);
497         namelen += dim;
498     }
499     else {
500         /* the element is a non-array class */
501         namebuf = DMNEW(char, namelen + 2 + dim);
502         namebuf[dim] = 'L';
503         memcpy(namebuf + dim + 1, element->name->text, namelen);
504         namelen += (2 + dim);
505         namebuf[namelen - 1] = ';';
506     }
507         memset(namebuf, '[', dim);
508
509         return get_array_class(utf_new(namebuf, namelen),
510                                                    element->classloader,
511                                                    element->classloader,
512                                                    link);
513 }
514
515
516 /* class_lookup_classref *******************************************************
517
518    Looks up the constant_classref for a given classname in the classref
519    tables of a class.
520
521    IN:
522        cls..............the class containing the reference
523            name.............the name of the class refered to
524
525     RETURN VALUE:
526            a pointer to a constant_classref, or 
527            NULL if the reference was not found
528    
529 *******************************************************************************/
530
531 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
532 {
533         constant_classref *ref;
534         extra_classref *xref;
535         int count;
536
537         CLASS_ASSERT(cls);
538         CLASS_ASSERT(name);
539         CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
540         
541         /* first search the main classref table */
542         count = cls->classrefcount;
543         ref = cls->classrefs;
544         for (; count; --count, ++ref)
545                 if (ref->name == name)
546                         return ref;
547
548         /* next try the list of extra classrefs */
549         for (xref = cls->extclassrefs; xref; xref = xref->next) {
550                 if (xref->classref.name == name)
551                         return &(xref->classref);
552         }
553
554         /* not found */
555         return NULL;
556 }
557
558
559 /* class_get_classref **********************************************************
560
561    Returns the constant_classref for a given classname.
562
563    IN:
564        cls..............the class containing the reference
565            name.............the name of the class refered to
566
567    RETURN VALUE:
568        a pointer to a constant_classref (never NULL)
569
570    NOTE:
571        The given name is not checked for validity!
572    
573 *******************************************************************************/
574
575 constant_classref *class_get_classref(classinfo *cls, utf *name)
576 {
577         constant_classref *ref;
578         extra_classref *xref;
579
580         CLASS_ASSERT(cls);
581         CLASS_ASSERT(name);
582
583         ref = class_lookup_classref(cls,name);
584         if (ref)
585                 return ref;
586
587         xref = NEW(extra_classref);
588         CLASSREF_INIT(xref->classref,cls,name);
589
590         xref->next = cls->extclassrefs;
591         cls->extclassrefs = xref;
592
593         return &(xref->classref);
594 }
595
596
597 /* class_get_classref_multiarray_of ********************************************
598
599    Returns an array type reference with the given dimension and element class
600    reference.
601
602    IN:
603        dim..............the requested dimension
604                             dim must be in [1;255]. This is NOT checked!
605            ref..............the component class reference
606
607    RETURN VALUE:
608        a pointer to the class reference for the array type
609
610    NOTE:
611        The referer of `ref` is used as the referer for the new classref.
612
613 *******************************************************************************/
614
615 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
616 {
617     s4 namelen;
618     char *namebuf;
619
620         CLASS_ASSERT(ref);
621         CLASS_ASSERT(dim >= 1 && dim <= 255);
622
623     /* Assemble the array class name */
624     namelen = ref->name->blength;
625     
626     if (ref->name->text[0] == '[') {
627         /* the element is itself an array */
628         namebuf = DMNEW(char, namelen + dim);
629         memcpy(namebuf + dim, ref->name->text, namelen);
630         namelen += dim;
631     }
632     else {
633         /* the element is a non-array class */
634         namebuf = DMNEW(char, namelen + 2 + dim);
635         namebuf[dim] = 'L';
636         memcpy(namebuf + dim + 1, ref->name->text, namelen);
637         namelen += (2 + dim);
638         namebuf[namelen - 1] = ';';
639     }
640         memset(namebuf, '[', dim);
641
642     return class_get_classref(ref->referer,utf_new(namebuf, namelen));
643 }
644
645 /* class_get_classref_component_of *********************************************
646
647    Returns the component classref of a given array type reference
648
649    IN:
650        ref..............the array type reference
651
652    RETURN VALUE:
653        a reference to the component class, or
654            NULL if `ref` is not an object array type reference
655
656    NOTE:
657        The referer of `ref` is used as the referer for the new classref.
658
659 *******************************************************************************/
660
661 constant_classref *class_get_classref_component_of(constant_classref *ref)
662 {
663         s4 namelen;
664         char *name;
665         
666         CLASS_ASSERT(ref);
667
668         name = ref->name->text;
669         if (*name++ != '[')
670                 return NULL;
671         
672         namelen = ref->name->blength - 1;
673         if (*name == 'L') {
674                 name++;
675                 namelen -= 2;
676         }
677         else if (*name != '[') {
678                 return NULL;
679         }
680
681     return class_get_classref(ref->referer, utf_new(name, namelen));
682 }
683
684
685 /*
686  * These are local overrides for various environment variables in Emacs.
687  * Please do not remove this and leave it at the end of the file, where
688  * Emacs will automagically detect them.
689  * ---------------------------------------------------------------------
690  * Local variables:
691  * mode: c
692  * indent-tabs-mode: t
693  * c-basic-offset: 4
694  * tab-width: 4
695  * End:
696  */