Authors: Edwin Steiner
- $Id: typeinfo.c 868 2004-01-10 20:12:10Z edwin $
+ $Id: typeinfo.c 922 2004-02-24 13:26:24Z edwin $
*/
return dst;
}
-#if 0
-typevector *
-typevectorset_copy_select(typevector *src,
- int retindex,void *retaddr,int size)
-{
- typevector *dst;
-
- for (;src; src=src->alt) {
- if (TYPEINFO_RETURNADDRESS(src->td[retindex].info) != retaddr)
- continue;
-
- dst = DNEW_TYPEVECTOR(size);
- memcpy(dst,src,TYPEVECTOR_SIZE(size));
- if (src->alt)
- dst->alt = typevectorset_copy_select(src->alt,retindex,retaddr,size);
- return dst;
- }
-
- return NULL;
-}
-
-void
-typevectorset_copy_select_to(typevector *src,typevector *dst,
- int retindex,void *retaddr,int size)
-{
- for (;src; src=src->alt) {
- if (TYPEINFO_RETURNADDRESS(src->td[retindex].info) != retaddr)
- continue;
-
- memcpy(dst,src,TYPEVECTOR_SIZE(size));
- if (src->alt)
- dst->alt = typevectorset_copy_select(src->alt,retindex,retaddr,size);
- return dst;
- }
-
- return NULL;
-}
-#endif
-
bool
typevectorset_checktype(typevector *vec,int index,int type)
{
void
typevectorset_store(typevector *vec,int index,int type,typeinfo *info)
{
- /* XXX check if a separator was overwritten */
do {
vec->td[index].type = type;
if (info)
{
typeinfo_retaddr_set *adr;
- /* XXX check if a separator was overwritten */
adr = (typeinfo_retaddr_set*) TYPEINFO_RETURNADDRESS(*info);
do {
vec->td[index].type = TYPE_ADDRESS;
void
typevectorset_store_twoword(typevector *vec,int index,int type)
{
- /* XXX check if a separator was overwritten */
do {
vec->td[index].type = type;
vec->td[index+1].type = TYPE_VOID;
dst->alt->k = dst->k + 1;
}
-#if 0
-void
-typevectorset_union(typevector *dst,typevector *v,int size)
-{
- while (dst->alt)
- dst = dst->alt;
- dst->alt = typevectorset_copy(v,size);
-}
-#endif
-
typevector *
typevectorset_select(typevector **set,int retindex,void *retaddr)
{
return selected;
}
-/* XXX delete */
-#if 0
-bool
-typevectorset_separable(typevector *vec,int size)
-{
- int i;
- typevector *v;
-
- for (i=0; i<size; ++i) {
- v = vec;
- do {
- if (!TYPEDESC_IS_RETURNADDRESS(v->td[i]))
- goto next_index;
-
- v = v->alt;
- if (!v) return true;
- } while (v);
- next_index:
- }
- return false;
-}
-#endif
-
bool
typevectorset_separable_with(typevector *set,typevector *add,int size)
{
if (!v && separable) return true;
} while (v);
next_index:
+ ;
}
return false;
}
return false;
}
-/* XXX If really a performance issue, this could become a macro. */
static
bool
classinfo_implements_interface(classinfo *cls,classinfo *interf)
bool
typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
{
- classinfo *cls;
-
- cls = value->typeclass;
-
/* DEBUG CHECK: dest must not have a merged list. */
#ifdef TYPEINFO_DEBUG
if (dest->merged)
panic("Internal error: typeinfo_is_assignable on merged destination.");
#endif
-
+
+ return typeinfo_is_assignable_to_classinfo(value,dest->typeclass);
+}
+
+bool
+typeinfo_is_assignable_to_classinfo(typeinfo *value,classinfo *dest)
+{
+ classinfo *cls;
+
+ cls = value->typeclass;
+
/* assignments of primitive values are not checked here. */
- if (!cls && !dest->typeclass)
+ if (!cls && !dest)
return true;
/* primitive and reference types are not assignment compatible. */
- if (!cls || !dest->typeclass)
+ if (!cls || !dest)
return false;
+#ifdef TYPEINFO_DEBUG
+ if (!dest->linked)
+ panic("Internal error: typeinfo_is_assignable_to_classinfo: unlinked class.");
+#endif
+
/* the null type can be assigned to any type */
if (TYPEINFO_IS_NULLTYPE(*value))
return true;
if (TYPEINFO_IS_NEWOBJECT(*value))
return false;
- if (dest->typeclass->flags & ACC_INTERFACE) {
+ if (dest->flags & ACC_INTERFACE) {
/* We are assigning to an interface type. */
- return merged_implements_interface(cls,value->merged,
- dest->typeclass);
+ return merged_implements_interface(cls,value->merged,dest);
}
- if (TYPEINFO_IS_ARRAY(*dest)) {
+ if (CLASS_IS_ARRAY(dest)) {
+ arraydescriptor *arraydesc = dest->vftbl->arraydesc;
+ int dimension = arraydesc->dimension;
+ classinfo *elementclass = (arraydesc->elementvftbl)
+ ? arraydesc->elementvftbl->class : NULL;
+
/* We are assigning to an array type. */
if (!TYPEINFO_IS_ARRAY(*value))
return false;
/* {Both value and dest are array types.} */
/* value must have at least the dimension of dest. */
- if (value->dimension < dest->dimension)
+ if (value->dimension < dimension)
return false;
- if (value->dimension > dest->dimension) {
+ if (value->dimension > dimension) {
/* value has higher dimension so we need to check
* if its component array can be assigned to the
* element type of dest */
+
+ if (!elementclass) return false;
- if (dest->elementclass->flags & ACC_INTERFACE) {
+ if (elementclass->flags & ACC_INTERFACE) {
/* We are assigning to an interface type. */
return classinfo_implements_interface(pseudo_class_Arraystub,
- dest->elementclass);
+ elementclass);
}
/* We are assigning to a class type. */
- return class_issubclass(pseudo_class_Arraystub,dest->elementclass);
+ return class_issubclass(pseudo_class_Arraystub,elementclass);
}
/* {value and dest have the same dimension} */
- if (value->elementtype != dest->elementtype)
+ if (value->elementtype != arraydesc->elementtype)
return false;
if (value->elementclass) {
* check if the elements are assignable.
*/
- if (dest->elementclass->flags & ACC_INTERFACE) {
+ if (elementclass->flags & ACC_INTERFACE) {
/* We are assigning to an interface type. */
return merged_implements_interface(value->elementclass,
value->merged,
- dest->elementclass);
+ elementclass);
}
/* We are assigning to a class type. */
- return class_issubclass(value->elementclass,dest->elementclass);
+ return class_issubclass(value->elementclass,elementclass);
}
return true;
if (cls->flags & ACC_INTERFACE)
cls = class_java_lang_Object;
- return class_issubclass(cls,dest->typeclass);
+ return class_issubclass(cls,dest);
}
/**********************************************************************/
classinfo *cls;
char *end;
- /* XXX simplify */
cls = class_from_descriptor(utf_ptr,end_ptr,&end,
CLASSLOAD_NULLPRIMITIVE
| CLASSLOAD_NEW
return;
}
- /* XXX find component class */
if (!TYPEINFO_IS_ARRAY(*srcarray))
panic("Trying to access component of non-array");
else {
TYPEINFO_INIT_PRIMITIVE(*dst);
}
-
- /* XXX assign directly ? */
-#if 0
- if ((dst->dimension = srcarray->dimension - 1) == 0) {
- dst->typeclass = srcarray->elementclass;
- dst->elementtype = 0;
- dst->elementclass = NULL;
- }
- else {
- dst->typeclass = srcarray->typeclass;
- dst->elementtype = srcarray->elementtype;
- dst->elementclass = srcarray->elementclass;
- }
-#endif
dst->merged = srcarray->merged;
}
TYPEINFO_ALLOCMERGED(dest->merged,count);
dest->merged->count = count;
- /* XXX use memcpy? */
srclist = src->merged->list;
destlist = dest->merged->list;
while (count--)
typeinfo_mergedlist *tmerged;
bool changed;
- /* XXX remove */
+ /* DEBUG */
/*
#ifdef TYPEINFO_DEBUG
typeinfo dbgx,dbgy;
/* (This case is very simple unless *both* x and y really represent
* merges of subclasses of clsx==clsy.)
*/
- /* XXX count this case for statistics */
if ((clsx == clsy) && (!mergedx || !mergedy)) {
return_simple_x:
- /* XXX remove */ /* log_text("return simple x"); */
+ /* DEBUG */ /* log_text("return simple x"); */
changed = (dest->merged != NULL);
TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
dest->merged = NULL;
*result = clsx;
- /* XXX remove */ /* log_text("returning"); */
+ /* DEBUG */ /* log_text("returning"); */
return changed;
}
if (clsy->flags & ACC_INTERFACE) {
/* We are merging two interfaces. */
/* {mergedy == NULL} */
- /* XXX: should we optimize direct superinterfaces? */
/* {We know that clsx!=clsy (see common case at beginning.)} */
*result = class_java_lang_Object;
* by y, too, so we have to add clsx to the mergedlist.
*/
- /* XXX if x has no superinterfaces we could return a simple java.lang.Object */
+ /* if x has no superinterfaces we could return a simple java.lang.Object */
common = class_java_lang_Object;
goto merge_with_simple_x;
int elementtype;
bool changed;
- /* XXX remove */
+ /* DEBUG */
/*
#ifdef TYPEINFO_DEBUG
typeinfo_print(stdout,dest,4);
return false;
}
- /* XXX remove */ /* log_text("Testing common case"); */
+ /* DEBUG */ /* log_text("Testing common case"); */
/* Common case: class dest == class y */
/* (This case is very simple unless *both* dest and y really represent
* merges of subclasses of class dest==class y.)
*/
- /* XXX count this case for statistics */
if ((dest->typeclass == y->typeclass) && (!dest->merged || !y->merged)) {
changed = (dest->merged != NULL);
- TYPEINFO_FREEMERGED_IF_ANY(dest->merged); /* XXX unify if? */
+ TYPEINFO_FREEMERGED_IF_ANY(dest->merged); /* unify if? */
dest->merged = NULL;
- /* XXX remove */ /* log_text("common case handled"); */
+ /* DEBUG */ /* log_text("common case handled"); */
return changed;
}
- /* XXX remove */ /* log_text("Handling null types"); */
+ /* DEBUG */ /* log_text("Handling null types"); */
/* Handle null types: */
if (TYPEINFO_IS_NULLTYPE(*y)) {
/* Handle merging of arrays: */
if (TYPEINFO_IS_ARRAY(*x) && TYPEINFO_IS_ARRAY(*y)) {
- /* XXX remove */ /* log_text("Handling arrays"); */
+ /* DEBUG */ /* log_text("Handling arrays"); */
/* Make x the one with lesser dimension */
if (x->dimension > y->dimension) {
elementclass,
x->merged,y->merged);
- /* XXX otimize this? */
- /* XXX remove */ /* log_text("finding resulting array class: "); */
+ /* DEBUG */ /* log_text("finding resulting array class: "); */
common = class_multiarray_of(dimension,elementclass);
- /* XXX remove */ /* utf_display(common->name); printf("\n"); */
+ /* DEBUG */ /* utf_display(common->name); printf("\n"); */
}
}
}
changed = true;
}
- /* XXX remove */ /* log_text("returning from merge"); */
+ /* DEBUG */ /* log_text("returning from merge"); */
return changed;
}