1 /* src/vm/class.c - class related functions
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
33 $Id: class.c 3260 2005-09-21 19:41:47Z twisti $
40 #include "vm/global.h"
41 #include "mm/memory.h"
43 #if defined(USE_THREADS)
44 # if defined(NATIVE_THREADS)
45 # include "threads/native/threads.h"
47 # include "threads/green/threads.h"
48 # include "threads/green/locks.h"
52 #include "toolbox/logging.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"
64 /******************************************************************************/
66 /******************************************************************************/
73 #define CLASS_ASSERT(cond) assert(cond)
75 #define CLASS_ASSERT(cond)
79 /* global variables ***********************************************************/
81 list unlinkedclasses; /* this is only used for eager class */
85 /* frequently used classes ****************************************************/
87 /* important system classes */
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;
100 /* system exception classes required in cacao */
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;
108 classinfo *class_java_lang_Exception = NULL;
109 classinfo *class_java_lang_ClassNotFoundException = NULL;
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;
122 /* some classes which may be used more often */
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;
131 classinfo *arrayclass_java_lang_Object = NULL;
134 /* pseudo classes for the typechecker */
136 classinfo *pseudo_class_Arraystub = NULL;
137 classinfo *pseudo_class_Null = NULL;
138 classinfo *pseudo_class_New = NULL;
141 /* class_set_packagename *******************************************************
143 Derive the package name from the class name and store it in the struct.
145 *******************************************************************************/
147 void class_set_packagename(classinfo *c)
149 char *p = UTF_END(c->name) - 1;
150 char *start = c->name->text;
152 /* set the package name */
153 /* classes in the unnamed package keep packagename == NULL */
155 if (c->name->text[0] == '[') {
156 /* set packagename of arrays to the element's package */
158 for (; *start == '['; start++);
160 /* skip the 'L' in arrays of references */
164 for (; (p > start) && (*p != '/'); --p);
166 c->packagename = utf_new(start, p - start);
169 for (; (p > start) && (*p != '/'); --p);
171 c->packagename = utf_new(start, p - start);
176 /* class_create_classinfo ******************************************************
178 Create a new classinfo struct. The class name is set to the given utf *,
179 most other fields are initialized to zero.
181 Note: classname may be NULL. In this case a not-yet-named classinfo is
182 created. The name must be filled in later and class_set_packagename
183 must be called after that.
185 *******************************************************************************/
187 classinfo *class_create_classinfo(utf *classname)
191 #if defined(STATISTICS)
193 count_class_infos += sizeof(classinfo);
196 /* we use a safe name for temporarily unnamed classes */
198 classname = utf_not_named_yet;
201 log_message_utf("Creating class: ", classname);
203 c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
204 /*c=NEW(classinfo);*/
208 c->packagename = NULL;
213 c->extclassrefs = NULL;
214 c->classrefcount = 0;
215 c->parseddescs = NULL;
216 c->parseddescsize = 0;
220 c->interfacescount = 0;
221 c->interfaces = NULL;
230 c->header.vftbl = NULL;
231 c->innerclasscount = 0;
232 c->innerclass = NULL;
234 c->initialized = false;
235 c->initializing = false;
236 c->classvftbl = false;
239 c->classloader = NULL;
240 c->sourcefile = NULL;
242 if (classname != utf_not_named_yet) {
243 class_set_packagename(c);
246 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
247 initObjectLock(&c->header);
253 /* class_freepool **************************************************************
255 Frees all resources used by this classes Constant Pool.
257 *******************************************************************************/
259 static void class_freecpool(classinfo *c)
265 if (c->cptags && c->cpinfos) {
266 for (idx = 0; idx < c->cpcount; idx++) {
267 tag = c->cptags[idx];
268 info = c->cpinfos[idx];
272 case CONSTANT_Fieldref:
273 case CONSTANT_Methodref:
274 case CONSTANT_InterfaceMethodref:
275 FREE(info, constant_FMIref);
277 case CONSTANT_Integer:
278 FREE(info, constant_integer);
281 FREE(info, constant_float);
284 FREE(info, constant_long);
286 case CONSTANT_Double:
287 FREE(info, constant_double);
289 case CONSTANT_NameAndType:
290 FREE(info, constant_nameandtype);
298 MFREE(c->cptags, u1, c->cpcount);
301 MFREE(c->cpinfos, voidptr, c->cpcount);
305 /* class_getconstant ***********************************************************
307 Retrieves the value at position 'pos' of the constantpool of a
308 class. If the type of the value is other than 'ctype', an error is
311 *******************************************************************************/
313 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
315 /* check index and type of constantpool entry */
316 /* (pos == 0 is caught by type comparison) */
318 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
319 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
323 return c->cpinfos[pos];
327 /* innerclass_getconstant ******************************************************
329 Like class_getconstant, but if cptags is ZERO, null is returned.
331 *******************************************************************************/
333 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
335 /* invalid position in constantpool */
336 if (pos >= c->cpcount) {
337 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
341 /* constantpool entry of type 0 */
345 /* check type of constantpool entry */
346 if (c->cptags[pos] != ctype) {
347 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
351 return c->cpinfos[pos];
355 /* class_free ******************************************************************
357 Frees all resources used by the class.
359 *******************************************************************************/
361 void class_free(classinfo *c)
369 MFREE(c->interfaces, classinfo*, c->interfacescount);
372 for (i = 0; i < c->fieldscount; i++)
373 field_free(&(c->fields[i]));
374 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
378 for (i = 0; i < c->methodscount; i++)
379 method_free(&(c->methods[i]));
380 MFREE(c->methods, methodinfo, c->methodscount);
383 if ((v = c->vftbl) != NULL) {
385 mem_free(v->arraydesc,sizeof(arraydescriptor));
387 for (i = 0; i < v->interfacetablelength; i++) {
388 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
390 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
392 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
393 sizeof(methodptr*) * (v->interfacetablelength -
394 (v->interfacetablelength > 0));
395 v = (vftbl_t*) (((methodptr*) v) -
396 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
401 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
403 /* if (c->classvftbl)
404 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
410 /* get_array_class *************************************************************
412 Returns the array class with the given name for the given
413 classloader, or NULL if an exception occurred.
415 Note: This function does eager loading.
417 *******************************************************************************/
419 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
420 java_objectheader *defloader,bool link)
424 /* lookup this class in the classcache */
425 c = classcache_lookup(initloader,name);
427 c = classcache_lookup_defined(defloader,name);
430 /* we have to create it */
431 c = class_create_classinfo(name);
432 c = load_newly_created_array(c,initloader);
438 CLASS_ASSERT(c->loaded);
439 CLASS_ASSERT(c->classloader == defloader);
441 if (link && !c->linked)
445 CLASS_ASSERT(!link || c->linked);
451 /* class_array_of **************************************************************
453 Returns an array class with the given component class. The array
454 class is dynamically created if neccessary.
456 *******************************************************************************/
458 classinfo *class_array_of(classinfo *component, bool link)
463 /* Assemble the array class name */
464 namelen = component->name->blength;
466 if (component->name->text[0] == '[') {
467 /* the component is itself an array */
468 namebuf = DMNEW(char, namelen + 1);
470 MCOPY(namebuf + 1, component->name->text, char, namelen);
474 /* the component is a non-array class */
475 namebuf = DMNEW(char, namelen + 3);
478 MCOPY(namebuf + 2, component->name->text, char, namelen);
479 namebuf[2 + namelen] = ';';
483 return get_array_class(utf_new(namebuf, namelen),
484 component->classloader,
485 component->classloader,
490 /* class_multiarray_of *********************************************************
492 Returns an array class with the given dimension and element class.
493 The array class is dynamically created if neccessary.
495 *******************************************************************************/
497 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
503 log_text("Invalid array dimension requested");
507 /* Assemble the array class name */
508 namelen = element->name->blength;
510 if (element->name->text[0] == '[') {
511 /* the element is itself an array */
512 namebuf = DMNEW(char, namelen + dim);
513 memcpy(namebuf + dim, element->name->text, namelen);
517 /* the element is a non-array class */
518 namebuf = DMNEW(char, namelen + 2 + dim);
520 memcpy(namebuf + dim + 1, element->name->text, namelen);
521 namelen += (2 + dim);
522 namebuf[namelen - 1] = ';';
524 memset(namebuf, '[', dim);
526 return get_array_class(utf_new(namebuf, namelen),
527 element->classloader,
528 element->classloader,
533 /* class_lookup_classref *******************************************************
535 Looks up the constant_classref for a given classname in the classref
539 cls..............the class containing the reference
540 name.............the name of the class refered to
543 a pointer to a constant_classref, or
544 NULL if the reference was not found
546 *******************************************************************************/
548 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
550 constant_classref *ref;
551 extra_classref *xref;
556 CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
558 /* first search the main classref table */
559 count = cls->classrefcount;
560 ref = cls->classrefs;
561 for (; count; --count, ++ref)
562 if (ref->name == name)
565 /* next try the list of extra classrefs */
566 for (xref = cls->extclassrefs; xref; xref = xref->next) {
567 if (xref->classref.name == name)
568 return &(xref->classref);
576 /* class_get_classref **********************************************************
578 Returns the constant_classref for a given classname.
581 cls..............the class containing the reference
582 name.............the name of the class refered to
585 a pointer to a constant_classref (never NULL)
588 The given name is not checked for validity!
590 *******************************************************************************/
592 constant_classref *class_get_classref(classinfo *cls, utf *name)
594 constant_classref *ref;
595 extra_classref *xref;
600 ref = class_lookup_classref(cls,name);
604 xref = NEW(extra_classref);
605 CLASSREF_INIT(xref->classref,cls,name);
607 xref->next = cls->extclassrefs;
608 cls->extclassrefs = xref;
610 return &(xref->classref);
614 /* class_get_self_classref *****************************************************
616 Returns the constant_classref to the class itself.
619 cls..............the class containing the reference
622 a pointer to a constant_classref (never NULL)
624 *******************************************************************************/
626 constant_classref *class_get_self_classref(classinfo *cls)
628 /* XXX this should be done in a faster way. Maybe always make */
629 /* the classref of index 0 a self reference. */
630 return class_get_classref(cls,cls->name);
633 /* class_get_classref_multiarray_of ********************************************
635 Returns an array type reference with the given dimension and element class
639 dim..............the requested dimension
640 dim must be in [1;255]. This is NOT checked!
641 ref..............the component class reference
644 a pointer to the class reference for the array type
647 The referer of `ref` is used as the referer for the new classref.
649 *******************************************************************************/
651 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
657 CLASS_ASSERT(dim >= 1 && dim <= 255);
659 /* Assemble the array class name */
660 namelen = ref->name->blength;
662 if (ref->name->text[0] == '[') {
663 /* the element is itself an array */
664 namebuf = DMNEW(char, namelen + dim);
665 memcpy(namebuf + dim, ref->name->text, namelen);
669 /* the element is a non-array class */
670 namebuf = DMNEW(char, namelen + 2 + dim);
672 memcpy(namebuf + dim + 1, ref->name->text, namelen);
673 namelen += (2 + dim);
674 namebuf[namelen - 1] = ';';
676 memset(namebuf, '[', dim);
678 return class_get_classref(ref->referer,utf_new(namebuf, namelen));
681 /* class_get_classref_component_of *********************************************
683 Returns the component classref of a given array type reference
686 ref..............the array type reference
689 a reference to the component class, or
690 NULL if `ref` is not an object array type reference
693 The referer of `ref` is used as the referer for the new classref.
695 *******************************************************************************/
697 constant_classref *class_get_classref_component_of(constant_classref *ref)
704 name = ref->name->text;
708 namelen = ref->name->blength - 1;
713 else if (*name != '[') {
717 return class_get_classref(ref->referer, utf_new(name, namelen));
722 * These are local overrides for various environment variables in Emacs.
723 * Please do not remove this and leave it at the end of the file, where
724 * Emacs will automagically detect them.
725 * ---------------------------------------------------------------------
728 * indent-tabs-mode: t