+ && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
+
+/******************************************************************************/
+/* DEBUG HELPERS */
+/******************************************************************************/
+
+#ifdef TYPEINFO_DEBUG
+#define TYPEINFO_ASSERT(cond) assert(cond)
+#else
+#define TYPEINFO_ASSERT(cond)
+#endif
+
+/**********************************************************************/
+/* TYPEVECTOR FUNCTIONS */
+/**********************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+
+/* typevector_copy *************************************************************
+
+ Return a copy of the given typevector.
+
+ IN:
+ src..............typevector set to copy, must be != NULL
+ size.............number of elements per typevector
+
+ RETURN VALUE:
+ a pointer to the new typevector set
+
+*******************************************************************************/
+
+varinfo *
+typevector_copy(varinfo *src, int size)
+{
+ varinfo *dst;
+
+ TYPEINFO_ASSERT(src);
+
+ dst = DNEW_TYPEVECTOR(size);
+ memcpy(dst,src,TYPEVECTOR_SIZE(size));
+
+ return dst;
+}
+
+/* typevector_copy_inplace *****************************************************
+
+ Copy a typevector to a given destination.
+
+ IN:
+ src..............typevector to copy, must be != NULL
+ dst..............destination to write the copy to
+ size.............number of elements per typevector
+
+*******************************************************************************/
+
+void
+typevector_copy_inplace(varinfo *src,varinfo *dst,int size)
+{
+ memcpy(dst,src,TYPEVECTOR_SIZE(size));
+}
+
+/* typevector_checktype ********************************************************
+
+ Check if the typevector contains a given type at a given index.
+
+ IN:
+ vec..............typevector set, must be != NULL
+ index............index of component to check
+ type.............TYPE_* constant to check against
+
+ RETURN VALUE:
+ true if the typevector contains TYPE at INDEX,
+ false otherwise
+
+*******************************************************************************/
+
+bool
+typevector_checktype(varinfo *vec,int index,int type)
+{
+ TYPEINFO_ASSERT(vec);
+
+ return vec[index].type == type;
+}
+
+/* typevector_checkreference ***************************************************
+
+ Check if the typevector contains a reference at a given index.
+
+ IN:
+ vec..............typevector, must be != NULL
+ index............index of component to check
+
+ RETURN VALUE:
+ true if the typevector contains a reference at INDEX,
+ false otherwise
+
+*******************************************************************************/
+
+bool
+typevector_checkreference(varinfo *vec, int index)
+{
+ TYPEINFO_ASSERT(vec);
+ return TYPEDESC_IS_REFERENCE(vec[index]);
+}
+
+/* typevectorset_checkretaddr **************************************************
+
+ Check if the typevectors contains a returnAddress at a given index.
+
+ IN:
+ vec..............typevector, must be != NULL
+ index............index of component to check
+
+ RETURN VALUE:
+ true if the typevector contains a returnAddress at INDEX,
+ false otherwise
+
+*******************************************************************************/
+
+bool
+typevector_checkretaddr(varinfo *vec,int index)
+{
+ TYPEINFO_ASSERT(vec);
+ return TYPEDESC_IS_RETURNADDRESS(vec[index]);
+}
+
+/* typevector_store ************************************************************
+
+ Store a type at a given index in the typevector.
+
+ IN:
+ vec..............typevector set, must be != NULL
+ index............index of component to set
+ type.............TYPE_* constant of type to set
+ info.............typeinfo of type to set, may be NULL,
+ if TYPE != TYPE_ADR
+
+*******************************************************************************/
+
+void
+typevector_store(varinfo *vec,int index,int type,typeinfo *info)
+{
+ TYPEINFO_ASSERT(vec);
+
+ vec[index].type = type;
+ if (info)
+ TYPEINFO_COPY(*info,vec[index].typeinfo);
+}
+
+/* typevector_store_retaddr ****************************************************
+
+ Store a returnAddress type at a given index in the typevector.
+
+ IN:
+ vec..............typevector set, must be != NULL
+ index............index of component to set
+ info.............typeinfo of the returnAddress.
+
+*******************************************************************************/
+
+void
+typevector_store_retaddr(varinfo *vec,int index,typeinfo *info)
+{
+ TYPEINFO_ASSERT(vec);
+ TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
+
+ vec[index].type = TYPE_ADR;
+ TYPEINFO_INIT_RETURNADDRESS(vec[index].typeinfo,
+ TYPEINFO_RETURNADDRESS(*info));
+}
+
+/* typevector_init_object ******************************************************
+
+ Replace all uninitialized object types in the typevector set which were
+ created by the given instruction by initialized object types.
+
+ IN:
+ set..............typevector set
+ ins..............instruction which created the uninitialized object type
+ initclass........class of the initialized object type to set
+ size.............number of elements per typevector
+
+ RETURN VALUE:
+ true.............success
+ false............an exception has been thrown
+
+ XXX maybe we should do the lazy resolving before calling this function
+
+*******************************************************************************/
+
+bool
+typevector_init_object(varinfo *set,void *ins,
+ classref_or_classinfo initclass,
+ int size)
+{
+ int i;
+
+ for (i=0; i<size; ++i) {
+ if (set[i].type == TYPE_ADR
+ && TYPEINFO_IS_NEWOBJECT(set[i].typeinfo)
+ && TYPEINFO_NEWOBJECT_INSTRUCTION(set[i].typeinfo) == ins)
+ {
+ if (!typeinfo_init_class(&(set[i].typeinfo),initclass))
+ return false;
+ }
+ }
+ return true;
+}
+
+/* typevector_merge ************************************************************
+
+ Merge a typevector with another one.
+ The given typevectors must have the same number of components.
+
+ IN:
+ m................method for exception messages
+ dst..............the first typevector
+ y................the second typevector
+ size.............number of elements per typevector
+
+ OUT:
+ *dst.............the resulting typevector
+
+ RETURN VALUE:
+ typecheck_TRUE...dst has been modified
+ typecheck_FALSE..dst has not been modified
+ typecheck_FAIL...an exception has been thrown
+
+*******************************************************************************/
+
+typecheck_result
+typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
+{
+ bool changed = false;
+ typecheck_result r;
+
+ varinfo *a = dst;
+ varinfo *b = y;
+ while (size--) {
+ if (a->type != TYPE_VOID && a->type != b->type) {
+ a->type = TYPE_VOID;
+ changed = true;
+ }
+ else if (a->type == TYPE_ADR) {
+ if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
+ /* 'a' is a returnAddress */
+ if (!TYPEINFO_IS_PRIMITIVE(b->typeinfo)
+ || (TYPEINFO_RETURNADDRESS(a->typeinfo)
+ != TYPEINFO_RETURNADDRESS(b->typeinfo)))
+ {
+ a->type = TYPE_VOID;
+ changed = true;
+ }
+ }
+ else {
+ /* 'a' is a reference */
+ if (TYPEINFO_IS_PRIMITIVE(b->typeinfo)) {
+ a->type = TYPE_VOID;
+ changed = true;
+ }
+ else {
+ /* two reference types are merged. There cannot be */
+ /* a merge error. In the worst case we get j.l.O. */
+ r = typeinfo_merge(m,&(a->typeinfo),&(b->typeinfo));
+ if (r == typecheck_FAIL)
+ return r;
+ changed |= r;
+ }
+ }
+ }
+ a++;
+ b++;
+ }
+ return changed;
+}