/* src/vm/class.hpp - class related functions header Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _CLASS_HPP #define _CLASS_HPP /* forward typedefs ***********************************************************/ typedef struct classinfo classinfo; typedef struct innerclassinfo innerclassinfo; typedef struct extra_classref extra_classref; #include "config.h" #include #include "vm/types.h" #if defined(ENABLE_JAVASE) # include "vm/annotation.hpp" #endif #include "vm/field.hpp" #include "vm/global.h" #include "vm/linker.hpp" #include "vm/loader.hpp" #include "vm/method.hpp" #include "vm/references.h" #include "vm/string.hpp" #include "vm/utf8.h" /* class state defines ********************************************************/ #define CLASS_LOADING 0x0001 #define CLASS_LOADED 0x0002 #define CLASS_LINKING 0x0004 #define CLASS_LINKED 0x0008 #define CLASS_INITIALIZING 0x0010 #define CLASS_INITIALIZED 0x0020 #define CLASS_ERROR 0x0040 /* some macros ****************************************************************/ #define CLASS_IS_OR_ALMOST_INITIALIZED(c) \ (((c)->state & CLASS_INITIALIZED) || ((c)->state & CLASS_INITIALIZING && class_initializing_thread_is_self((c)))) /* classinfo ******************************************************************/ /* We define this dummy structure of java_lang_Class so we can bootstrap cacaoh without needing a java_lang_Class.h file. Whether the size of the dummy structure is big enough is checked during runtime in vm_create. */ typedef struct { java_object_t header; #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) intptr_t padding[4]; #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) intptr_t padding[19]; #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) intptr_t padding[3]; #else # error unknown classpath configuration #endif } dummy_java_lang_Class; struct threadobject; struct classinfo { /* class structure */ dummy_java_lang_Class object; s4 flags; /* ACC flags */ utf *name; /* class name */ s4 cpcount; /* number of entries in constant pool */ u1 *cptags; /* constant pool tags */ void* *cpinfos; /* pointer to constant pool info structures */ s4 classrefcount; /* number of symbolic class references */ constant_classref *classrefs; /* table of symbolic class references */ extra_classref *extclassrefs; /* additional classrefs */ classinfo *super; /* super class */ classinfo *sub; /* sub class pointer */ classinfo *nextsub; /* pointer to next class in sub class list */ int32_t interfacescount; /* number of interfaces */ classinfo **interfaces; /* super interfaces */ int32_t fieldscount; /* number of fields */ fieldinfo *fields; /* field table */ int32_t methodscount; /* number of methods */ methodinfo *methods; /* method table */ s4 state; /* current class state */ s4 index; /* hierarchy depth (classes) or index */ /* (interfaces) */ s4 instancesize; /* size of an instance of this class */ struct threadobject *initializing_thread; vftbl_t *vftbl; /* pointer to virtual function table */ methodinfo *finalizer; /* finalizer method */ u2 innerclasscount; /* number of inner classes */ innerclassinfo *innerclass; classref_or_classinfo declaringclass; classref_or_classinfo enclosingclass; /* enclosing class */ constant_nameandtype *enclosingmethod; /* enclosing method */ utf *packagename; /* full name of the package */ utf *sourcefile; /* SourceFile attribute */ #if defined(ENABLE_JAVASE) utf *signature; /* Signature attribute */ #if defined(ENABLE_ANNOTATIONS) /* All the annotation attributes are NULL (and not a zero length array) */ /* if there is nothing. */ java_object_t *annotations; /* annotations of this class */ java_object_t *method_annotations; /* array of annotations of the methods */ java_object_t *method_parameterannotations; /* array of parameter */ /* annotations of the methods */ java_object_t *method_annotationdefaults; /* array of annotation default */ /* values of the methods */ java_object_t *field_annotations; /* array of annotations of the fields */ #endif #endif classloader_t *classloader; /* NULL for bootstrap classloader */ #if defined(ENABLE_JAVASE) # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) java_object_t *protectiondomain; java_objectarray_t *signers; # endif #endif }; /* innerclassinfo *************************************************************/ struct innerclassinfo { classref_or_classinfo inner_class; /* inner class pointer */ classref_or_classinfo outer_class; /* outer class pointer */ utf *name; /* innerclass name */ s4 flags; /* ACC flags */ }; /* extra_classref ************************************************************** for classrefs not occurring within descriptors *******************************************************************************/ struct extra_classref { extra_classref *next; constant_classref classref; }; /* inline functions ***********************************************************/ #ifdef __cplusplus extern "C" { #endif /** * Returns the classname of the class, where slashes ('/') are * replaced by dots ('.'). * * @param c class to get name of * @return classname */ inline static java_handle_t* class_get_classname(classinfo* c) { java_handle_t *s; /* Create a java string. */ s = javastring_new_slash_to_dot(c->name); return s; } /* class_is_primitive ********************************************************** Checks if the given class is a primitive class. *******************************************************************************/ static inline bool class_is_primitive(classinfo *c) { if (c->flags & ACC_CLASS_PRIMITIVE) return true; return false; } /* class_is_anonymousclass ***************************************************** Checks if the given class is an anonymous class. *******************************************************************************/ static inline bool class_is_anonymousclass(classinfo *c) { if (c->flags & ACC_CLASS_ANONYMOUS) return true; return false; } /* class_is_array ************************************************************** Checks if the given class is an array class. *******************************************************************************/ static inline bool class_is_array(classinfo *c) { if (!(c->state & CLASS_LINKED)) if (!link_class(c)) return false; return (c->vftbl->arraydesc != NULL); } /* class_is_interface ********************************************************** Checks if the given class is an interface. *******************************************************************************/ static inline bool class_is_interface(classinfo *c) { if (c->flags & ACC_INTERFACE) return true; return false; } /* class_is_localclass ********************************************************* Checks if the given class is a local class. *******************************************************************************/ static inline bool class_is_localclass(classinfo *c) { if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c)) return true; return false; } /* class_is_memberclass ******************************************************** Checks if the given class is a member class. *******************************************************************************/ static inline bool class_is_memberclass(classinfo *c) { if (c->flags & ACC_CLASS_MEMBER) return true; return false; } /* class_get_classloader ******************************************************* Return the classloader of the given class. *******************************************************************************/ static inline classloader_t *class_get_classloader(classinfo *c) { classloader_t *cl; cl = c->classloader; /* The classloader may be NULL. */ return cl; } /* class_get_superclass ******************************************************** Return the super class of the given class. *******************************************************************************/ static inline classinfo *class_get_superclass(classinfo *c) { /* For interfaces we return NULL. */ if (c->flags & ACC_INTERFACE) return NULL; /* For java/lang/Object, primitive-type and Void classes c->super is NULL and we return NULL. */ return c->super; } /* function prototypes ********************************************************/ classinfo *class_create_classinfo(utf *u); void class_postset_header_vftbl(void); classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd); void class_set_packagename(classinfo *c); bool class_load_attributes(classbuffer *cb); /* retrieve constantpool element */ void* class_getconstant(classinfo *c, u4 pos, u4 ctype); void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype); /* frees all resources used by the class */ void class_free(classinfo *); /* return an array class with the given component class */ classinfo *class_array_of(classinfo *component,bool link); /* return an array class with the given dimension and element class */ classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link); /* return a classref for the given class name */ /* (does a linear search!) */ constant_classref *class_lookup_classref(classinfo *cls,utf *name); /* return a classref for the given class name */ /* (does a linear search!) */ constant_classref *class_get_classref(classinfo *cls,utf *name); /* return a classref to the class itself */ /* (does a linear search!) */ constant_classref *class_get_self_classref(classinfo *cls); /* return a classref for an array with the given dimension of with the */ /* given component type */ constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref); /* return a classref for the component type of the given array type */ constant_classref *class_get_classref_component_of(constant_classref *ref); /* get a class' field by name and descriptor */ fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc); /* search 'classinfo'-structure for a field with the specified name */ fieldinfo *class_findfield_by_name(classinfo *c, utf *name); /* search class for a field */ fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer); /* search for a method with a specified name and descriptor */ methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc); methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest); methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception); methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception); bool class_issubclass(classinfo *sub, classinfo *super); bool class_isanysubclass(classinfo *sub, classinfo *super); bool class_is_arraycompatible(arraydescriptor *desc, arraydescriptor *target); bool class_is_assignable_from(classinfo *to, classinfo *from); bool class_is_instance(classinfo *c, java_handle_t *h); classloader_t *class_get_classloader(classinfo *c); classinfo *class_get_superclass(classinfo *c); classinfo *class_get_componenttype(classinfo *c); java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly); java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly); java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly); java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly); classinfo *class_get_declaringclass(classinfo *c); classinfo *class_get_enclosingclass(classinfo *c); java_handle_t* class_get_enclosingconstructor(classinfo *c); methodinfo* class_get_enclosingmethod_raw(classinfo *c); java_handle_t* class_get_enclosingmethod(classinfo *c); java_handle_objectarray_t *class_get_interfaces(classinfo *c); java_handle_bytearray_t *class_get_annotations(classinfo *c); int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib); java_handle_t *class_get_name(classinfo *c); #if defined(ENABLE_JAVASE) utf *class_get_signature(classinfo *c); #endif bool class_initializing_thread_is_self(classinfo *c); /* some debugging functions */ #if !defined(NDEBUG) void class_printflags(classinfo *c); void class_print(classinfo *c); void class_println(classinfo *c); void class_classref_print(constant_classref *cr); void class_classref_println(constant_classref *cr); void class_classref_or_classinfo_print(classref_or_classinfo c); void class_classref_or_classinfo_println(classref_or_classinfo c); #endif /* debug purposes */ void class_showmethods(classinfo *c); void class_showconstantpool(classinfo *c); #ifdef __cplusplus } #endif #endif /* _CLASS_HPP */ /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: c * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: * vim:noexpandtab:sw=4:ts=4: */