Define functions prototypes
[cacao.git] / typeinfo.c
index 9496b12cc732f275f8d176e0180d20a8a6802a64..1c7f3328d4166547419d08e15b1dc285fb053d58 100644 (file)
@@ -26,7 +26,7 @@
 
    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 $
 
 */
 
@@ -61,45 +61,6 @@ typevectorset_copy(typevector *src,int k,int size)
        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)
 {
@@ -183,7 +144,6 @@ typevectorset_mergedtypeinfo(typevector *vec,int index,typeinfo *temp)
 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)
@@ -198,7 +158,6 @@ typevectorset_store_retaddr(typevector *vec,int index,typeinfo *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;
@@ -212,7 +171,6 @@ typevectorset_store_retaddr(typevector *vec,int index,typeinfo *info)
 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;
@@ -304,16 +262,6 @@ typevectorset_add(typevector *dst,typevector *v,int size)
        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)
 {
@@ -332,29 +280,6 @@ 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)
 {
@@ -379,6 +304,7 @@ typevectorset_separable_with(typevector *set,typevector *add,int size)
                        if (!v && separable) return true;
                } while (v);
        next_index:
+               ;
        }
        return false;
 }
@@ -440,7 +366,6 @@ interface_extends_interface(classinfo *cls,classinfo *interf)
     return false;
 }
 
-/* XXX If really a performance issue, this could become a macro. */
 static
 bool
 classinfo_implements_interface(classinfo *cls,classinfo *interf)
@@ -502,24 +427,35 @@ merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
 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;
@@ -528,13 +464,17 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
     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;
@@ -542,27 +482,29 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
         /* {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) {
@@ -570,16 +512,16 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
              * 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;
@@ -591,7 +533,7 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
     if (cls->flags & ACC_INTERFACE)
         cls = class_java_lang_Object;
     
-    return class_issubclass(cls,dest->typeclass);
+    return class_issubclass(cls,dest);
 }
 
 /**********************************************************************/
@@ -605,7 +547,6 @@ typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr)
     classinfo *cls;
     char *end;
 
-    /* XXX simplify */
     cls = class_from_descriptor(utf_ptr,end_ptr,&end,
                                                                CLASSLOAD_NULLPRIMITIVE
                                                                | CLASSLOAD_NEW
@@ -766,7 +707,6 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
         return;
     }
     
-    /* XXX find component class */
     if (!TYPEINFO_IS_ARRAY(*srcarray))
         panic("Trying to access component of non-array");
 
@@ -777,20 +717,6 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
     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;
 }
@@ -811,7 +737,6 @@ typeinfo_clone(typeinfo *src,typeinfo *dest)
         TYPEINFO_ALLOCMERGED(dest->merged,count);
         dest->merged->count = count;
 
-        /* XXX use memcpy? */
         srclist = src->merged->list;
         destlist = dest->merged->list;
         while (count--)
@@ -1046,7 +971,7 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     typeinfo_mergedlist *tmerged;
     bool changed;
 
-    /* XXX remove */
+    /* DEBUG */
     /*
 #ifdef TYPEINFO_DEBUG
     typeinfo dbgx,dbgy;
@@ -1065,15 +990,14 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     /* (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;
     }
     
@@ -1091,7 +1015,6 @@ typeinfo_merge_nonarrays(typeinfo *dest,
         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;
@@ -1125,7 +1048,7 @@ typeinfo_merge_nonarrays(typeinfo *dest,
          * 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;
@@ -1190,7 +1113,7 @@ typeinfo_merge(typeinfo *dest,typeinfo* y)
     int elementtype;
     bool changed;
 
-    /* XXX remove */
+    /* DEBUG */
     /*
 #ifdef TYPEINFO_DEBUG
     typeinfo_print(stdout,dest,4);
@@ -1233,22 +1156,21 @@ typeinfo_merge(typeinfo *dest,typeinfo* y)
         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)) {
@@ -1268,7 +1190,7 @@ typeinfo_merge(typeinfo *dest,typeinfo* 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) {
@@ -1317,10 +1239,9 @@ typeinfo_merge(typeinfo *dest,typeinfo* y)
                                                     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"); */
             }
         }
     }
@@ -1357,7 +1278,7 @@ typeinfo_merge(typeinfo *dest,typeinfo* y)
         changed = true;
     }
 
-    /* XXX remove */ /* log_text("returning from merge"); */
+    /* DEBUG */ /* log_text("returning from merge"); */
     
     return changed;
 }