X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=typeinfo.h;h=302a7e4b5c5cd6c1e55fc0980e15b982c6fdae87;hb=2ffcaa73cddc90a880868b80f0d39e9502976ae6;hp=d038f602aec85aea3a221ae77e848177b7dd2e6f;hpb=b7bb69c5392120d426eee7d3c828e22330d8a7d1;p=cacao.git diff --git a/typeinfo.h b/typeinfo.h index d038f602a..302a7e4b5 100644 --- a/typeinfo.h +++ b/typeinfo.h @@ -26,7 +26,7 @@ Authors: Edwin Steiner - $Id: typeinfo.h 795 2003-12-16 22:27:52Z edwin $ + $Id: typeinfo.h 887 2004-01-19 12:14:39Z edwin $ */ @@ -40,38 +40,26 @@ typedef struct typeinfo typeinfo; typedef struct typeinfo_mergedlist typeinfo_mergedlist; +typedef struct typedescriptor typedescriptor; +typedef struct typevector typevector; +typedef struct typeinfo_retaddr_set typeinfo_retaddr_set; -/* global variables ***********************************************************/ - -/* XXX move this documentation to global.h */ -/* The following classinfo pointers are used internally by the type system. - * Please do not use them directly, use the TYPEINFO_ macros instead. - */ +/* data structures for the type system ****************************************/ -/* - * pseudo_class_Arraystub - * (extends Object implements Cloneable, java.io.Serializable) +/* The typeinfo structure stores detailed information on address types. + * (stack elements, variables, etc. with type == TYPE_ADR.) * - * If two arrays of incompatible component types are merged, - * the resulting reference has no accessible components. - * The result does, however, implement the interfaces Cloneable - * and java.io.Serializable. This pseudo class is used internally - * to represent such results. (They are *not* considered arrays!) + * There are two kinds of address types which can are distinguished by + * the value of the typeclass field: * - * pseudo_class_Null + * 1) typeclass == NULL: returnAddress type + * use TYPEINFO_IS_PRIMITIVE to test for this * - * This pseudo class is used internally to represent the - * null type. - */ - -/* data structures for the type system ****************************************/ - -/* The typeinfo structure stores detailed information on reference types. - * (stack elements, variables, etc. with type == TYPE_ADR.) - * XXX: exclude ReturnAddresses? + * 2) typeclass != NULL: reference type + * use TYPEINFO_IS_REFERENCE to test for this * - * For primitive types either there is no typeinfo allocated or the - * typeclass pointer in the typeinfo struct is NULL. + * Note: For non-address types either there is no typeinfo allocated + * or the fields of the typeinfo struct contain undefined values! * * CAUTION: The typeinfo structure should be considered opaque outside of * typeinfo.[ch]. Please use the macros and functions defined here to @@ -83,38 +71,69 @@ typedef struct typeinfo_mergedlist typeinfo_mergedlist; * * A) typeclass == NULL * - * In this case the other fields of the structure - * are INVALID. + * This is a returnAddress type. The interpretation of the + * elementclass field depends on wether this typeinfo describes + * a stack slot or a local variable: + * + * stack slot: elementclass is a pointer to a + * typeinfo_retaddr_set which contains a return target for + * every vector in the current set of local variable vectors. + * local variable: elementclass is the return target (when cast + * to basicblock *) + * + * Use TYPEINFO_IS_PRIMITIVE to check for this. + * Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass. + * Don't access other fields of the struct. * * B) typeclass == pseudo_class_Null * - * XXX + * This is the null-reference type. Use TYPEINFO_IS_NULLTYPE to check for this. + * Don't access other fields of the struct. + * + * C) typeclass == pseudo_class_New * - * C) typeclass is an array class + * This is a 'uninitialized object' type. elementclass can be + * cast to instruction* and points to the NEW instruction + * responsible for creating this type. * - * XXX + * Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in + * elementclass. + * Don't access other fields of the struct. * * D) typeclass == pseudo_class_Arraystub * - * XXX + * See global.h for a describes of pseudo_class_Arraystub. + * Otherwise like a normal class reference type. + * Don't access other fields of the struct. * - * E) typeclass is an interface + * E) typeclass is an array class * - * XXX + * An array reference. + * elementclass...typeclass of the element type + * dimension......dimension of the array (>=1) + * elementtype....element type (ARRAYTYPE_...) + * merged.........mergedlist of the element type * - * F) typeclass is a (non-pseudo-)class != java.lang.Object + * F) typeclass is an interface * - * XXX + * An interface reference type. + * Don't access other fields of the struct. + * + * G) typeclass is a (non-pseudo-,non-array-)class != java.lang.Object + * + * A class reference type. * All classinfos in u.merged.list (if any) are - * subclasses of typeclass. + * subclasses of typeclass (no interfaces or array classes). + * Don't access other fields of the struct. * - * G) typeclass is java.lang.Object + * H) typeclass is java.lang.Object * - * XXX + * The most general kind of reference type. * In this case u.merged.count and u.merged.list * are valid and may be non-zero. - * The classinfos in u.merged.list (if any) can be - * classes, interfaces or pseudo classes. + * The classinfos in u.merged.list (if any) may be + * classes, interfaces and pseudo classes. + * Don't access other fields of the struct. */ /* The following algorithm is used to determine if the type described @@ -122,7 +141,7 @@ typedef struct typeinfo_mergedlist typeinfo_mergedlist; * * 1) If typeclass is X or a subinterface of X the answer is "yes". * 2) If typeclass is a (pseudo) class implementing X the answer is "yes". - * 3) XXX If typeclass is not an array and u.merged.count>0 + * 3) If typeclass is not an array and u.merged.count>0 * and all classes/interfaces in u.merged.list implement X * the answer is "yes". * 4) If none of the above is true the answer is "no". @@ -134,26 +153,66 @@ typedef struct typeinfo_mergedlist typeinfo_mergedlist; * access typeinfo structures! */ struct typeinfo { - classinfo *typeclass; - classinfo *elementclass; /* valid if dimension>0 */ - typeinfo_mergedlist *merged; - u1 dimension; - u1 elementtype; /* valid if dimension>0 */ + classinfo *typeclass; + classinfo *elementclass; /* valid if dimension>0 */ /* various uses! */ + typeinfo_mergedlist *merged; + u1 dimension; + u1 elementtype; /* valid if dimension>0 */ }; struct typeinfo_mergedlist { - s4 count; - classinfo *list[1]; /* variable length! */ + s4 count; + classinfo *list[1]; /* variable length! */ +}; + +struct typeinfo_retaddr_set { + typeinfo_retaddr_set *alt; /* next alternative in set */ + void *addr; /* return address */ +}; + +struct typedescriptor { + typeinfo info; /* valid if type == TYPE_ADR */ + u1 type; /* basic type (TYPE_INT, ...) */ +}; + +/* typevectors are used to store the types of local variables */ + +struct typevector { + typevector *alt; /* next alternative in typevector set */ + int k; /* for lining up with the stack set */ + typedescriptor td[1]; /* variable length! */ }; /****************************************************************************/ /* MACROS */ /****************************************************************************/ -/* NOTE: These macros take typeinfo *structs* not pointers as arguments. - * You have to dereference any pointers. +/* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as + * arguments. You have to dereference any pointers. */ +/* typevectors **************************************************************/ + +#define TYPEVECTOR_SIZE(size) \ + ((sizeof(typevector) - sizeof(typedescriptor)) \ + + (size)*sizeof(typedescriptor)) + +#define DNEW_TYPEVECTOR(size) \ + ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size))) + +#define DMNEW_TYPEVECTOR(num,size) \ + ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size))) + +#define MGET_TYPEVECTOR(array,index,size) \ + ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index))) + +#define COPY_TYPEVECTORSET(src,dst,size) \ + do {memcpy(dst,src,TYPEVECTOR_SIZE(size)); \ + dst->k = 0; \ + if ((src)->alt) { \ + (dst)->alt = typevectorset_copy((src)->alt,1,size); \ + }} while(0) + /* internally used macros ***************************************************/ /* internal, don't use this explicitly! */ @@ -182,6 +241,10 @@ struct typeinfo_mergedlist { #define TYPEINFO_IS_NEWOBJECT(info) \ ((info).typeclass == pseudo_class_New) +/* only use this if TYPEINFO_IS_PRIMITIVE returned true! */ +#define TYPEINFO_RETURNADDRESS(info) \ + ((void *)(info).elementclass) + /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */ #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \ ((void *)(info).elementclass) @@ -215,6 +278,20 @@ struct typeinfo_mergedlist { ( TYPEINFO_IS_ARRAY(info) \ && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) ) +#define TYPE_IS_RETURNADDRESS(type,info) \ + ( ((type)==TYPE_ADDRESS) \ + && TYPEINFO_IS_PRIMITIVE(info) ) + +#define TYPE_IS_REFERENCE(type,info) \ + ( ((type)==TYPE_ADDRESS) \ + && !TYPEINFO_IS_PRIMITIVE(info) ) + +#define TYPEDESC_IS_RETURNADDRESS(td) \ + TYPE_IS_RETURNADDRESS((td).type,(td).info) + +#define TYPEDESC_IS_REFERENCE(td) \ + TYPE_IS_REFERENCE((td).type,(td).info) + /* queries allowing the null type ********************************************/ #define TYPEINFO_MAYBE_ARRAY(info) \ @@ -235,6 +312,13 @@ struct typeinfo_mergedlist { (info).dimension = 0; \ (info).elementtype = 0;} while(0) +#define TYPEINFO_INIT_RETURNADDRESS(info,adr) \ + do {(info).typeclass = NULL; \ + (info).elementclass = (classinfo*) (adr); \ + (info).merged = NULL; \ + (info).dimension = 0; \ + (info).elementtype = 0;} while(0) + #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \ do {(info).typeclass = (cinfo); \ (info).elementclass = NULL; \ @@ -275,30 +359,6 @@ struct typeinfo_mergedlist { typeinfo_init_from_descriptor(&(info), \ (fi)->descriptor->text,utf_end((fi)->descriptor)); -/* macros for writing types (destination must have been initialized) ********/ -/* XXX delete them? */ -#if 0 - -#define TYPEINFO_PUT_NULLTYPE(info) \ - do {(info).typeclass = pseudo_class_Null;} while(0) - -#define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo) \ - do {(info).typeclass = (cinfo);} while(0) - -#define TYPEINFO_PUT_CLASSINFO(info,cls) \ - do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \ - if ((cls)->vftbl->arraydesc->elementvftbl) \ - (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \ - (info).dimension = (cls)->vftbl->arraydesc->dimension; \ - (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \ - }} while(0) - -/* srcarray must be an array (not checked) */ -#define TYPEINFO_PUT_COMPONENT(srcarray,dst) \ - do {typeinfo_put_component(&(srcarray),&(dst));} while(0) - -#endif - /* macros for copying types (destinition is not checked or freed) ***********/ /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */ @@ -316,6 +376,33 @@ struct typeinfo_mergedlist { /* FUNCTIONS */ /****************************************************************************/ +/* typevector functions *****************************************************/ + +/* element read-only access */ +bool typevectorset_checktype(typevector *set,int index,int type); +bool typevectorset_checkreference(typevector *set,int index); +bool typevectorset_checkretaddr(typevector *set,int index); +int typevectorset_copymergedtype(typevector *set,int index,typeinfo *dst); +typeinfo *typevectorset_mergedtypeinfo(typevector *set,int index,typeinfo *temp); +int typevectorset_mergedtype(typevector *set,int index,typeinfo *temp,typeinfo **result); + +/* element write access */ +void typevectorset_store(typevector *set,int index,int type,typeinfo *info); +void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info); +void typevectorset_store_twoword(typevector *set,int index,int type); +void typevectorset_init_object(typevector *set,void *ins,classinfo *initclass,int size); + +/* vector functions */ +bool typevector_separable_from(typevector *a,typevector *b,int size); +bool typevector_merge(typevector *dst,typevector *y,int size); + +/* vector set functions */ +typevector *typevectorset_copy(typevector *src,int k,int size); +bool typevectorset_separable_with(typevector *set,typevector *add,int size); +bool typevectorset_collapse(typevector *dst,int size); +void typevectorset_add(typevector *dst,typevector *v,int size); +typevector *typevectorset_select(typevector **set,int retindex,void *retaddr); + /* inquiry functions (read-only) ********************************************/ bool typeinfo_is_array(typeinfo *info); @@ -324,6 +411,7 @@ bool typeinfo_is_array_of_refs(typeinfo *info); bool typeinfo_implements_interface(typeinfo *info,classinfo *interf); bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest); +bool typeinfo_is_assignable_to_classinfo(typeinfo *value,classinfo *dest); /* initialization functions *************************************************/ @@ -335,6 +423,10 @@ void typeinfo_init_from_method_args(utf *desc,u1 *typebuf, typeinfo *infobuf, int buflen,bool twoword, int *returntype,typeinfo *returntypeinfo); +int typedescriptors_init_from_method_args(typedescriptor *td, + utf *desc, + int buflen,bool twoword, + typedescriptor *returntype); void typeinfo_clone(typeinfo *src,typeinfo *dest); @@ -355,6 +447,10 @@ void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc); void typeinfo_print(FILE *file,typeinfo *info,int indent); void typeinfo_print_short(FILE *file,typeinfo *info); void typeinfo_print_type(FILE *file,int type,typeinfo *info); +void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info); +void typedescriptor_print(FILE *file,typedescriptor *td); +void typevector_print(FILE *file,typevector *vec,int size); +void typevectorset_print(FILE *file,typevector *set,int size); #endif /* TYPEINFO_DEBUG */