[kaffe] CVS kaffe (dalibor): Moved type handling and second verifier pass into own modules

Kaffe CVS cvs-commits at kaffe.org
Fri Mar 5 06:01:03 PST 2004


PatchSet 4478 
Date: 2004/03/05 13:45:29
Author: dalibor
Branch: HEAD
Tag: (none) 
Log:
Moved type handling and second verifier pass into own modules

2004-03-05  Dalibor Topic <robilad at kaffe.org>

        kaffe/kaffevm/verify-type.c,
        kaffe/kaffevm/verify-type.h,
        kaffe/kaffevm/verify2.c:
        New files.

        kaffe/kaffevm/Makefile.am:
        (libkaffevm_la_SOURCES): Added verify-type.c, verify2.c.
        (noinst_HEADERS): Added verify-type.h.

        * kaffe/kaffevm/Makefile.in:
        Regenerated.

        * kaffe/kaffevm/baseClasses.c,
        kaffe/kaffevm/verify-block.h,
        kaffe/kaffevm/verify-uninit.h:
        Include verify-type.h.

        * kaffe/kaffevm/verify-debug.c,
        kaffe/kaffevm/verify-debug.h:
        (printConstantPoolEntry, printConstantPool) New functions.
        (indent, indent2) New fields.

        * kaffe/kaffevm/verify.c,
        kaffe/kaffevm/verify.h,
        (printConstantPoolEntry, printConstantPool, indent, indent2)
        Moved over to kaffe/kaffevm/verify-debug.c and
        kaffe/kaffevm/verify-debug.h.
        (checkField, checkConstructor, checkMethodStaticConstraints,
        checkAbstractMethod, isMethodVoid, verify2) Moved over to
        kaffe/kaffevm/verify2.c.
        Moved over handling of types to kaffe/kaffevm/verify-type.c
        and kaffe/kaffevm/verify-type.h.

Members: 
	ChangeLog:1.2058->1.2059 
	kaffe/kaffevm/Makefile.am:1.53->1.54 
	kaffe/kaffevm/Makefile.in:1.136->1.137 
	kaffe/kaffevm/baseClasses.c:1.45->1.46 
	kaffe/kaffevm/verify-block.h:1.1->1.2 
	kaffe/kaffevm/verify-debug.c:1.2->1.3 
	kaffe/kaffevm/verify-debug.h:1.2->1.3 
	kaffe/kaffevm/verify-type.c:INITIAL->1.1 
	kaffe/kaffevm/verify-type.h:INITIAL->1.1 
	kaffe/kaffevm/verify-uninit.h:1.2->1.3 
	kaffe/kaffevm/verify.c:1.70->1.71 
	kaffe/kaffevm/verify.h:1.10->1.11 
	kaffe/kaffevm/verify2.c:INITIAL->1.1 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2058 kaffe/ChangeLog:1.2059
--- kaffe/ChangeLog:1.2058	Tue Mar  2 17:48:44 2004
+++ kaffe/ChangeLog	Fri Mar  5 13:45:29 2004
@@ -1,3 +1,38 @@
+2004-03-05  Dalibor Topic <robilad at kaffe.org>
+
+        kaffe/kaffevm/verify-type.c,
+        kaffe/kaffevm/verify-type.h,
+        kaffe/kaffevm/verify2.c:
+	New files.
+
+        kaffe/kaffevm/Makefile.am:
+        (libkaffevm_la_SOURCES): Added verify-type.c, verify2.c.
+        (noinst_HEADERS): Added verify-type.h.
+
+        * kaffe/kaffevm/Makefile.in:
+	Regenerated.
+
+        * kaffe/kaffevm/baseClasses.c,
+        kaffe/kaffevm/verify-block.h,
+        kaffe/kaffevm/verify-uninit.h:
+	Include verify-type.h.
+
+        * kaffe/kaffevm/verify-debug.c,
+	kaffe/kaffevm/verify-debug.h:
+	(printConstantPoolEntry, printConstantPool) New functions.
+	(indent, indent2) New fields.
+
+        * kaffe/kaffevm/verify.c,
+        kaffe/kaffevm/verify.h,
+	(printConstantPoolEntry, printConstantPool, indent, indent2)
+	Moved over to kaffe/kaffevm/verify-debug.c and 
+	kaffe/kaffevm/verify-debug.h.
+	(checkField, checkConstructor, checkMethodStaticConstraints,
+	checkAbstractMethod, isMethodVoid, verify2) Moved over to 
+	kaffe/kaffevm/verify2.c.
+	Moved over handling of types to kaffe/kaffevm/verify-type.c
+	and kaffe/kaffevm/verify-type.h.
+
 2004-03-02  Dalibor Topic <robilad at kaffe.org>
 
         * kaffe/kaffevm/verify-block.c,
Index: kaffe/kaffe/kaffevm/Makefile.am
diff -u kaffe/kaffe/kaffevm/Makefile.am:1.53 kaffe/kaffe/kaffevm/Makefile.am:1.54
--- kaffe/kaffe/kaffevm/Makefile.am:1.53	Tue Mar  2 17:48:46 2004
+++ kaffe/kaffe/kaffevm/Makefile.am	Fri Mar  5 13:45:31 2004
@@ -93,9 +93,11 @@
 	gcFuncs.c \
 	gcRefs.c \
 	verify.c \
+	verify2.c \
 	verify-block.c \
 	verify-debug.c \
 	verify-sigstack.c \
+	verify-type.c \
 	verify-uninit.c
 
 noinst_HEADERS = \
@@ -142,6 +144,7 @@
 	verify-block.h \
 	verify-debug.h \
 	verify-sigstack.h \
+	verify-type.h \
 	verify-uninit.h
 
 gc-mem.c: stamp-h01
Index: kaffe/kaffe/kaffevm/Makefile.in
diff -u kaffe/kaffe/kaffevm/Makefile.in:1.136 kaffe/kaffe/kaffevm/Makefile.in:1.137
--- kaffe/kaffe/kaffevm/Makefile.in:1.136	Tue Mar  2 17:48:46 2004
+++ kaffe/kaffe/kaffevm/Makefile.in	Fri Mar  5 13:45:31 2004
@@ -80,8 +80,8 @@
 	locks.lo lookup.lo object.lo readClass.lo sha-1.lo soft.lo \
 	stackTrace.lo stats.lo string.lo stringParsing.lo support.lo \
 	thread.lo utf8const.lo gcFuncs.lo gcRefs.lo verify.lo \
-	verify-block.lo verify-debug.lo verify-sigstack.lo \
-	verify-uninit.lo
+	verify2.lo verify-block.lo verify-debug.lo verify-sigstack.lo \
+	verify-type.lo verify-uninit.lo
 am__objects_1 = gc-mem.lo md.lo
 nodist_libkaffevm_la_OBJECTS = $(am__objects_1)
 libkaffevm_la_OBJECTS = $(am_libkaffevm_la_OBJECTS) \
@@ -113,8 +113,9 @@
 @AMDEP_TRUE@	./$(DEPDIR)/verify-block.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/verify-debug.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/verify-sigstack.Plo \
+ at AMDEP_TRUE@	./$(DEPDIR)/verify-type.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/verify-uninit.Plo \
- at AMDEP_TRUE@	./$(DEPDIR)/verify.Plo
+ at AMDEP_TRUE@	./$(DEPDIR)/verify.Plo ./$(DEPDIR)/verify2.Plo
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
@@ -439,9 +440,11 @@
 	gcFuncs.c \
 	gcRefs.c \
 	verify.c \
+	verify2.c \
 	verify-block.c \
 	verify-debug.c \
 	verify-sigstack.c \
+	verify-type.c \
 	verify-uninit.c
 
 noinst_HEADERS = \
@@ -488,6 +491,7 @@
 	verify-block.h \
 	verify-debug.h \
 	verify-sigstack.h \
+	verify-type.h \
 	verify-uninit.h
 
 CLEANFILES = so_locations
@@ -600,8 +604,10 @@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify-block.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify-debug.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify-sigstack.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify-type.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify-uninit.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/verify2.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
Index: kaffe/kaffe/kaffevm/baseClasses.c
diff -u kaffe/kaffe/kaffevm/baseClasses.c:1.45 kaffe/kaffe/kaffevm/baseClasses.c:1.46
--- kaffe/kaffe/kaffevm/baseClasses.c:1.45	Thu Aug  7 21:05:27 2003
+++ kaffe/kaffe/kaffevm/baseClasses.c	Fri Mar  5 13:45:31 2004
@@ -38,7 +38,7 @@
 #include "feedback.h"
 #include "debugFile.h"
 #include "fileSections.h"
-#include "verify.h"
+#include "verify-type.h"
 
 Utf8Const* init_name;
 Utf8Const* final_name;
Index: kaffe/kaffe/kaffevm/verify-block.h
diff -u kaffe/kaffe/kaffevm/verify-block.h:1.1 kaffe/kaffe/kaffevm/verify-block.h:1.2
--- kaffe/kaffe/kaffevm/verify-block.h:1.1	Tue Mar  2 17:48:47 2004
+++ kaffe/kaffe/kaffevm/verify-block.h	Fri Mar  5 13:45:31 2004
@@ -14,7 +14,7 @@
 #define VERIFY_BLOCK_H
 
 #include "gtypes.h"
-#include "verify.h"
+#include "verify-type.h"
 
 /*
  * basic block header information
Index: kaffe/kaffe/kaffevm/verify-debug.c
diff -u kaffe/kaffe/kaffevm/verify-debug.c:1.2 kaffe/kaffe/kaffevm/verify-debug.c:1.3
--- kaffe/kaffe/kaffevm/verify-debug.c:1.2	Tue Mar  2 17:48:47 2004
+++ kaffe/kaffe/kaffevm/verify-debug.c	Fri Mar  5 13:45:31 2004
@@ -17,6 +17,94 @@
 /* for debugging */
 #if !(defined(NDEBUG) || !defined(KAFFE_VMDEBUG))
 
+const char* indent  = "                ";
+const char* indent2 = "                        ";
+
+uint32
+printConstantPoolEntry(const Hjava_lang_Class* class, uint32 idx)
+{
+	const constants* pool = CLASS_CONSTANTS(class);
+	
+	switch (pool->tags[idx]) {
+	case CONSTANT_Utf8:
+		DBG(VERIFY2, dprintf("   UTF8: %s", CONST_UTF2CHAR(idx, pool)) );
+		break;
+			
+			
+	case CONSTANT_Long:
+	case CONSTANT_Double:
+		idx++;
+	case CONSTANT_Integer:
+	case CONSTANT_Float:
+		DBG(VERIFY2, dprintf("   NUMERICAL"); );
+		break;
+			
+			
+	case CONSTANT_ResolvedString:
+	case CONSTANT_ResolvedClass:
+		DBG(VERIFY2, dprintf("   RESOLVED: %s",
+				     ((Hjava_lang_Class*)pool->data[idx])->name->data); );
+		break;
+			
+			
+			
+	case CONSTANT_Class:
+		DBG(VERIFY2, dprintf("   UNRESOLVED CLASS: %s", CLASS_NAMED(idx, pool)); );
+		break;
+			
+	case CONSTANT_String:
+		DBG(VERIFY2, dprintf("   STRING: %s", CONST_STRING_NAMED(idx, pool)); );
+		break;
+			
+			
+			
+	case CONSTANT_Fieldref:
+		DBG(VERIFY2, dprintf("   FIELDREF: %s  --type--  %s",
+				     FIELDREF_NAMED(idx, pool), FIELDREF_SIGD(idx, pool)); );
+		break;
+			
+	case CONSTANT_Methodref:
+		DBG(VERIFY2, dprintf("   METHODREF: %s  --type--  %s",
+				     METHODREF_NAMED(idx, pool), METHODREF_SIGD(idx, pool)); );
+		break;
+			
+			
+	case CONSTANT_InterfaceMethodref:
+		DBG(VERIFY2, dprintf("   INTERFACEMETHODREF: %s  --type--  %s",
+				     INTERFACEMETHODREF_NAMED(idx, pool), INTERFACEMETHODREF_SIGD(idx, pool)); );
+		break;
+			
+			
+	case CONSTANT_NameAndType:
+		DBG(VERIFY2, dprintf("   NAMEANDTYPE: %s  --and--  %s",
+				     NAMEANDTYPE_NAMED(idx, pool), NAMEANDTYPE_SIGD(idx, pool)); );
+		break;
+			
+	default:
+		DBG(VERIFY2, dprintf("   *** UNRECOGNIZED CONSTANT POOL ENTRY in class %s *** ",
+				     CLASS_CNAME(class)); );
+	}
+	
+	return idx;
+}
+
+void
+printConstantPool(const Hjava_lang_Class* class)
+{
+	uint32 idx;
+	const constants *pool = CLASS_CONSTANTS(class);
+	
+	DBG(VERIFY2, dprintf("    CONSTANT POOL FOR %s\n", class->name->data); );
+	
+	for (idx = 1; idx < pool->size; idx++) {
+		DBG(VERIFY2, dprintf("      %d", idx); );
+		
+		idx = printConstantPoolEntry(class, idx);
+		
+		DBG(VERIFY2, dprintf("\n"); );
+	}
+}
+
 /*
  * printInstruction()
  *     prints out a string representation of the instruction.
Index: kaffe/kaffe/kaffevm/verify-debug.h
diff -u kaffe/kaffe/kaffevm/verify-debug.h:1.2 kaffe/kaffe/kaffevm/verify-debug.h:1.3
--- kaffe/kaffe/kaffevm/verify-debug.h:1.2	Tue Mar  2 17:48:47 2004
+++ kaffe/kaffe/kaffevm/verify-debug.h	Fri Mar  5 13:45:31 2004
@@ -18,6 +18,11 @@
 #include "verify-block.h"
 
 #if defined(KAFFE_VMDEBUG)
+extern const char* indent;
+extern const char* indent2;
+
+extern uint32 printConstantPoolEntry(const Hjava_lang_Class* class, uint32 idx);
+extern void printConstantPool(const Hjava_lang_Class* class);
 extern void printInstruction(const int opcode);
 extern void printType(const Type*);
 extern void printBlock(const Method* method, const BlockInfo* binfo, const char* indent);
===================================================================
Checking out kaffe/kaffe/kaffevm/verify-type.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/verify-type.c,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/verify-type.c	Fri Mar  5 13:49:14 2004
@@ -0,0 +1,538 @@
+/*
+ * verify-type.c
+ *
+ * Copyright 2004
+ *   Kaffe.org contributors. See ChangeLog for details. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ *
+ * Code for handing of types in the verifier.
+ */
+
+#include "itypes.h"
+#include "soft.h"
+#include "verify-debug.h"
+#include "verify-type.h"
+#include "verify-uninit.h"
+
+/*
+ * types for type checking (pass 3b)
+ */
+static Type  verify_UNSTABLE;
+Type* TUNSTABLE = &verify_UNSTABLE;
+
+static Type  verify_INT;
+Type* TINT = &verify_INT;
+       
+static Type  verify_FLOAT;
+Type* TFLOAT = &verify_FLOAT;
+       
+static Type  verify_LONG;
+Type* TLONG = &verify_LONG;
+       
+static Type  verify_DOUBLE;
+Type* TDOUBLE = &verify_DOUBLE;
+
+/* used for the second space of LONGs and DOUBLEs
+ * in local variables or on the operand stack
+ */
+static Type  _WIDE;
+Type* TWIDE = &_WIDE;
+
+bool
+isWide(const Type * tinfo)
+{
+	return (tinfo->data.class == TWIDE->data.class);
+}
+
+static Type  verify_NULL;
+Type* TNULL = &verify_NULL;
+
+bool
+isNull(const Type * tinfo)
+{
+	return (tinfo->data.class == TNULL->data.class);
+}
+
+static const char* OBJECT_SIG  = "Ljava/lang/Object;";
+static Type  verify_OBJ;
+Type* TOBJ = &verify_OBJ;
+
+static const char* OBJARR_SIG = "[Ljava/lang/Object;";
+static Type  verify_OBJARR;
+Type* TOBJARR = &verify_OBJARR;
+
+static const char* STRING_SIG = "Ljava/lang/String;";
+static Type  verify_STRING;
+Type* TSTRING = &verify_STRING;
+
+static const char* CHARARR_SIG = "[C";
+static Type  verify_CHARARR;
+Type* TCHARARR = &verify_CHARARR;
+
+static const char* BYTEARR_SIG = "[B";
+static Type  verify_BYTEARR;
+Type* TBYTEARR = &verify_BYTEARR;
+
+static const char* BOOLARR_SIG = "[Z";
+static Type  verify_BOOLARR;
+Type* TBOOLARR = &verify_BOOLARR;
+
+static const char* SHORTARR_SIG = "[S";
+static Type  verify_SHORTARR;
+Type* TSHORTARR = &verify_SHORTARR;
+
+static const char* INTARR_SIG = "[I";
+static Type  verify_INTARR;
+Type* TINTARR = &verify_INTARR;
+
+static const char* LONGARR_SIG = "[J";
+static Type  verify_LONGARR;
+Type* TLONGARR = &verify_LONGARR;
+
+static const char* FLOATARR_SIG = "[F";
+static Type  verify_FLOATARR;
+Type* TFLOATARR = &verify_FLOATARR;
+
+static const char* DOUBLEARR_SIG = "[D";
+static Type  verify_DOUBLEARR;
+Type* TDOUBLEARR = &verify_DOUBLEARR;
+
+/*
+ * Initialize Type structures needed for verification
+ */
+void
+initVerifierPrimTypes(void)
+{
+	TUNSTABLE->tinfo = TINFO_SYSTEM;
+	TUNSTABLE->data.class = (Hjava_lang_Class*)TUNSTABLE;
+	
+	TWIDE->tinfo = TINFO_SYSTEM;
+	TWIDE->data.class = (Hjava_lang_Class*)TWIDE;
+	
+	
+	TINT->tinfo = TINFO_PRIMITIVE;
+	TINT->data.class = intClass;
+	
+	TLONG->tinfo = TINFO_PRIMITIVE;
+	TLONG->data.class = longClass;
+	
+	TFLOAT->tinfo = TINFO_PRIMITIVE;
+	TFLOAT->data.class = floatClass;
+	
+	TDOUBLE->tinfo = TINFO_PRIMITIVE;
+	TDOUBLE->data.class = doubleClass;
+	
+	
+	TNULL->tinfo = TINFO_CLASS;
+	TNULL->data.class = (Hjava_lang_Class*)TNULL;
+	
+	TOBJ->tinfo = TINFO_SIG;
+	TOBJ->data.sig = OBJECT_SIG;
+	
+	TOBJARR->tinfo = TINFO_SIG;	
+	TOBJARR->data.sig = OBJARR_SIG;
+	
+	
+	TSTRING->data.sig = STRING_SIG;
+	TSTRING->tinfo = TINFO_SIG;
+	
+	
+	TCHARARR->tinfo = TINFO_SIG;
+	TCHARARR->data.sig = CHARARR_SIG;
+	
+	TBYTEARR->tinfo = TINFO_SIG;
+	TBYTEARR->data.sig = BYTEARR_SIG;
+	
+	TBOOLARR->tinfo = TINFO_SIG;
+	TBOOLARR->data.sig = BOOLARR_SIG;
+	
+	TSHORTARR->tinfo = TINFO_SIG;
+	TSHORTARR->data.sig = SHORTARR_SIG;
+	
+	TINTARR->tinfo = TINFO_SIG;
+	TINTARR->data.sig = INTARR_SIG;
+	
+	TLONGARR->tinfo = TINFO_SIG;
+	TLONGARR->data.sig = LONGARR_SIG;
+	
+	TFLOATARR->tinfo = TINFO_SIG;
+	TFLOATARR->data.sig = FLOATARR_SIG;
+	
+	TDOUBLEARR->tinfo = TINFO_SIG;	
+	TDOUBLEARR->data.sig = DOUBLEARR_SIG;
+}
+
+
+/*
+ * resolveType()
+ *     Ensures that the type is a pointer to an instance of Hjava_lang_Class.
+ */
+void
+resolveType(errorInfo* einfo, Hjava_lang_Class* this, Type *type)
+{
+	const char* sig;
+	char* tmp = NULL;
+
+	if (type->tinfo & TINFO_NAME) {
+		sig = type->data.sig;
+		
+		if (*sig != '[') {
+			tmp = checkPtr(gc_malloc((strlen(sig) + 3) * sizeof(char), GC_ALLOC_VERIFIER));
+			sprintf(tmp, "L%s;", sig);
+			sig = tmp;
+		}
+		
+		type->tinfo = TINFO_CLASS;
+		type->data.class = getClassFromSignature(sig, this->loader, einfo);
+		
+		if (tmp) {
+			gc_free(tmp);
+		}
+	}
+	else if (type->tinfo & TINFO_SIG) {
+		type->tinfo = TINFO_CLASS;
+		type->data.class = getClassFromSignature(type->data.sig, this->loader, einfo);
+	}
+}
+
+
+/*
+ * mergeTypes()
+ *     merges two types, t1 and t2, into t2.  this result could
+ *     be a common superclass, a common class that both types implement, or,
+ *     in the event that the types are not compatible, TUNSTABLE.
+ *
+ * returns whether an actual merger was made (i.e. they weren't the same type)
+ *
+ * note: the precedence of merged types goes (from highest to lowest):
+ *     actual pointer to Hjava_lang_Class*
+ *     TINFO_SIG
+ *     TINFO_NAME
+ *
+ * TODO: right now the priority is to be a common superclass, as stated in
+ *       the JVML2 specs.  a better verification technique might check this first,
+ *       and then check interfaces that both classes implement.  of course, depending
+ *       on the complexity of the inheritance hirearchy, this could take a lot of time.
+ *       
+ *       the ideal solution is to remember *all* possible highest resolution types,
+ *       which, of course, would require allocating more memory on the fly, etc., so,
+ *       at least for now, we're not really even considering it.
+ */
+bool
+mergeTypes(errorInfo* einfo, Hjava_lang_Class* this,
+	   Type* t1, Type* t2)
+{
+	if (IS_ADDRESS(t1) || IS_ADDRESS(t2)) {
+	        /* if one of the types is TADDR, the other one must also be TADDR */
+		if (t1->tinfo != t2->tinfo) {
+			return false;
+		}
+		
+		/* TODO: should this be an error if they don't agree? */
+		t2->tinfo = t1->tinfo;
+		return true;
+	}
+	else if (t2->data.class == TUNSTABLE->data.class || sameType(t1, t2)) {
+		return false;
+	}
+	else if (t1->tinfo & TINFO_UNINIT || t2->tinfo & TINFO_UNINIT ||
+		 !isReference(t1) || !isReference(t2)) {
+		
+		*t2 = *TUNSTABLE;
+		return true;
+	}
+	/* references only from here on out */
+	else if (t1->data.class == TOBJ->data.class) {
+		*t2 = *t1;
+		return true;
+	}
+	
+	
+	/* not equivalent, must resolve them */
+	resolveType(einfo, this, t1);
+	if (t1->data.class == NULL) {
+		return false;
+	}
+
+	resolveType(einfo, this, t2);
+	if (t2->data.class == NULL) {
+		return false;
+	}
+	
+	if (CLASS_IS_INTERFACE(t1->data.class) &&
+	    instanceof_interface(t1->data.class, t2->data.class)) {
+	
+		/* t1 is an interface and t2 implements it,
+		 * so the interface is the merged type.
+		 */
+
+		*t2 = *t1;
+		
+		return true;
+	
+	} else if (CLASS_IS_INTERFACE(t2->data.class) &&
+		   instanceof_interface(t2->data.class, t1->data.class)) {
+		
+		/* same as above, but we don't need to merge, since
+		 * t2 already is the merged type
+		 */
+
+		return false;
+	} else {
+		/*
+		 * neither of the types is an interface, so we have to
+		 * check for common superclasses. Only merge iff t2 is
+		 * not the common superclass.
+		 */
+		Hjava_lang_Class *tmp = t2->data.class;
+		
+		t2->data.class = getCommonSuperclass(t1->data.class, t2->data.class);
+		
+		return tmp != t2->data.class;
+	} 
+}
+
+
+/*
+ * returns the first (highest) common superclass of classes A and B.
+ *
+ * precondition: neither type is an array type
+ *               nor is either a primitive type
+ */
+Hjava_lang_Class*
+getCommonSuperclass(Hjava_lang_Class* t1, Hjava_lang_Class* t2)
+{
+	Hjava_lang_Class* A;
+	Hjava_lang_Class* B;
+	
+	for (A = t1; A != NULL; A = A->superclass) {
+		for (B = t2; B != NULL; B = B->superclass) {
+			if (A == B) return A;
+		}
+	}
+	
+	/* error of some kind...at the very least, we shoulda gotten to Object
+	 * when traversing the class hirearchy
+	 */
+	return TUNSTABLE->data.class;
+}
+
+
+/*
+ * isReference()
+ *    returns whether the type is a reference type
+ */
+bool
+isReference(const Type* type)
+{
+	return (type->tinfo & TINFO_NAME ||
+		type->tinfo & TINFO_SIG ||
+		type->tinfo & TINFO_CLASS ||
+		type->tinfo & TINFO_UNINIT);
+}
+
+/*
+ * isArray()
+ *     returns whether the Type is an array Type
+ */
+bool
+isArray(const Type* type)
+{
+	if (!isReference(type)) {
+		return false;
+	}
+	else if (type->tinfo & TINFO_NAME || type->tinfo & TINFO_SIG) {
+		return (*(type->data.sig) == '[');
+	}
+	else if (type->tinfo != TINFO_CLASS) {
+		return false;
+	}
+	else {
+		return (*(CLASS_CNAME(type->data.class)) == '[');
+	}
+}
+
+
+/*
+ * sameType()
+ *     returns whether two Types are effectively equivalent.
+ */
+bool
+sameType(Type* t1, Type* t2)
+{
+	switch (t1->tinfo) {
+	case TINFO_SYSTEM:
+		return (t2->tinfo == TINFO_SYSTEM &&
+			t1->data.class == t2->data.class);
+		
+	case TINFO_ADDR:
+		return (t2->tinfo == TINFO_ADDR &&
+			t1->data.addr == t2->data.addr);
+		
+	case TINFO_PRIMITIVE:
+		return (t2->tinfo == TINFO_PRIMITIVE &&
+			t1->data.class == t2->data.class);
+		
+	case TINFO_UNINIT:
+	case TINFO_UNINIT_SUPER:
+		return (t2->tinfo & TINFO_UNINIT &&
+			(t1->data.uninit == t2->data.uninit ||
+			 sameRefType(&(t1->data.uninit->type),
+				     &(t2->data.uninit->type))));
+		
+	default:
+		DBG(VERIFY3, dprintf("%ssameType(): unrecognized tinfo (%d)\n", indent, t1->tinfo); );
+		return false;
+		
+	case TINFO_SIG:
+	case TINFO_NAME:
+	case TINFO_CLASS:
+		return ((t2->tinfo == TINFO_SIG ||
+			 t2->tinfo == TINFO_NAME || 
+			 t2->tinfo == TINFO_CLASS) &&
+			sameRefType(t1,t2));
+	}
+}
+
+/*
+ * sameRefType()
+ *     returns whether two Types are effectively equivalent.
+ *
+ *     pre: t1 and t2 are both reference types
+ */
+bool
+sameRefType(Type* t1, Type* t2)
+{
+	const char* sig1 = NULL;
+	const char* sig2 = NULL;
+	uint32 len1, len2;
+	
+	if (isNull(t1) || isNull(t2)) {
+		return true;
+	}
+	
+	if (t1->tinfo & TINFO_NAME) {
+		sig1 = t1->data.name;
+		
+		if (t2->tinfo & TINFO_NAME) {
+			return (!strcmp(sig1, t2->data.name));
+		}
+		else if (t2->tinfo & TINFO_SIG) {
+			sig2 = t2->data.sig;
+			
+			len1 = strlen(sig1);
+			len2 = strlen(sig2);
+			
+			sig2++;
+			if ((len1 + 2 != len2) || strncmp(sig1, sig2, len1))
+				return false;
+		}
+		else {
+			if (strcmp(sig1, CLASS_CNAME(t2->data.class)))
+				return false;
+		}
+		
+		*t1 = *t2;
+		return true;
+	}
+	else if (t1->tinfo & TINFO_SIG) {
+		sig1 = t1->data.sig;
+		
+		if (t2->tinfo & TINFO_SIG) {
+			return (!strcmp(sig1, t2->data.sig));
+		}
+		else if (t2->tinfo & TINFO_NAME) {
+			sig2 = t2->data.name;
+			
+			len1 = strlen(sig1);
+			len2 = strlen(sig2);
+			sig1++;
+			
+			if ((len1 != len2 + 2) || strncmp(sig1, sig2, len2))
+				return false;
+			
+			*t2 = *t1;
+			return true;
+		}
+		else {
+			sig2 = CLASS_CNAME(t2->data.class);
+			
+			len1 = strlen(sig1);
+			len2 = strlen(sig2);
+			sig1++;
+			
+			if ((len1 != len2 + 2) || strncmp(sig1, sig2, len2))
+				return false;
+			
+			*t1 = *t2;
+			return true;
+		}
+	}
+	else {
+		sig1 = CLASS_CNAME(t1->data.class);
+		
+		if (t2->tinfo & TINFO_SIG) {
+			sig2 = t2->data.sig;
+			
+			len1 = strlen(sig1);
+			len2 = strlen(sig2);
+			sig2++;
+			if ((len1 + 2 != len2) || strncmp(sig1, sig2, len1))
+				return false;
+			
+			*t2 = *t1;
+			return true;
+		}
+		else if (t2->tinfo & TINFO_NAME) {
+			sig2 = t2->data.name;
+			
+			if (strcmp(sig1, sig2))
+				return false;
+			
+			*t2 = *t1;
+			return true;
+		}
+		else {
+		        /* we should never get here */
+			sig2 = CLASS_CNAME(t2->data.class);
+			return (!strcmp(sig1, sig2));
+		}
+	}
+}
+
+
+/*
+ * returns whether t2 can be a t1
+ */
+bool
+typecheck(errorInfo* einfo, Hjava_lang_Class* this, Type* t1, Type* t2)
+{
+	DBG(VERIFY3, dprintf("%stypechecking ", indent); printType(t1); dprintf("  vs.  "); printType(t2); dprintf("\n"); );
+	
+	if (sameType(t1, t2)) {
+		return true;
+	}
+	else if (t1->tinfo & TINFO_UNINIT || t2->tinfo & TINFO_UNINIT) {
+		return false;
+	}
+	else if (!isReference(t1) || !isReference(t2)) {
+		return false;
+	}
+	else if (sameType(t1, TOBJ)) {
+		return true;
+	}
+
+	resolveType(einfo, this, t1);
+	if (t1->data.class == NULL) {
+		return false;
+	}
+
+	resolveType(einfo, this, t2);
+	if (t2->data.class == NULL) {
+		return false;
+	}
+
+	return instanceof(t1->data.class, t2->data.class);
+}
===================================================================
Checking out kaffe/kaffe/kaffevm/verify-type.h
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/verify-type.h,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/verify-type.h	Fri Mar  5 13:49:14 2004
@@ -0,0 +1,112 @@
+/*
+ * verify-type.h
+ *
+ * Copyright 2004
+ *   Kaffe.org contributors. See ChangeLog for details. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ *
+ * Interface to code for handing of types in the verifier.
+ */
+
+#if !defined(VERIFY_TYPE_H)
+#define VERIFY_TYPE_H
+
+#include "classMethod.h"
+
+typedef struct Type
+{
+	uint32 tinfo;
+	
+	union {
+	        /* different ways to refer to an object reference */
+		const char* name;
+		const char* sig;
+		Hjava_lang_Class* class;
+		
+	        /* uninitialized object reference */
+		struct unitialized_types_double_list* uninit;
+		
+	        /* list of supertypes in the event of multiple inheritence of interfaces. */
+		Hjava_lang_Class** supertypes;
+		
+	        /* return address for TINFO_ADDR */
+		uint32 addr;
+	} data;
+} Type;
+
+/* status flags for opstack/local info arrays
+ *
+ *   TINFO_SYSTEM       internal type, such as UNSTABLE or VOID
+ *   TINFO_ADDR         return address type
+ *   TINFO_PRIMITIVE    Type.data.class is some primitive class, like intClass
+ *   TINFO_CLASS        Type.data.class
+ *   TINFO_NAME         Type.data.name represents the class' fully qualified name
+ *   TINFO_SIG          Type.data.sig  represents the class' fully qualified type signature
+ *   TINFO_UNINIT       is a class instance created by NEW that has yet to be initialized.
+ *                      the type is really an (UninitializedType*), so that dups, moves, etc. ensure that whatever
+ *                      copies of the type are around are all initialized when the <init>() is called.
+ *   TINFO_UNINIT_SUPER reserved for the self-reference in a constructor method.  when the receiver of a call to <init>()
+ *                      is of type TINFO_UNINIT_SUPER, then the <init>() referenced may be in the current class of in its
+ *                      superclass.
+ *   TINFO_SUPERLIST    a list of supertypes.  used when merging two types that have multiple common supertypes.
+ *                      this can occur with the multiple inheritence of interfaces.
+ *                      the zeroth element is always a common superclass, the rest are common superinterfaces.
+ */
+#define TINFO_SYSTEM       0
+#define TINFO_ADDR         1
+#define TINFO_PRIMITIVE    2
+#define TINFO_SIG          4
+#define TINFO_NAME         8
+#define TINFO_CLASS        16
+#define TINFO_UNINIT       32
+#define TINFO_UNINIT_SUPER 96
+#define TINFO_SUPERLIST    128
+
+#define IS_ADDRESS(_TINFO) ((_TINFO)->tinfo & TINFO_ADDR)
+#define IS_PRIMITIVE_TYPE(_TINFO) ((_TINFO)->tinfo & TINFO_PRIMITIVE)
+
+/*
+ * types for type checking (pass 3b)
+ */
+extern Type* TUNSTABLE;
+
+extern Type* TINT;
+extern Type* TFLOAT;
+extern Type* TLONG;
+extern Type* TDOUBLE;
+extern Type* TNULL;
+extern Type* TWIDE;
+extern Type* TOBJ;
+
+extern Type* TOBJARR;
+extern Type* TCHARARR;
+extern Type* TBYTEARR;
+extern Type* TBOOLARR;
+extern Type* TSHORTARR;
+extern Type* TINTARR;
+extern Type* TLONGARR;
+extern Type* TFLOATARR;
+extern Type* TDOUBLEARR;
+
+extern Type* TSTRING;
+
+extern void initVerifierPrimTypes(void);
+extern bool isNull(const Type * tinfo);
+extern bool isWide(const Type * tinfo);
+
+extern bool isReference(const Type* type);
+extern bool isArray(const Type* type);
+extern bool sameRefType(Type* t1, Type* t2);
+extern bool sameType(Type* t1, Type* t2);
+extern void resolveType(errorInfo* einfo, Hjava_lang_Class* this, Type *type);
+
+extern bool mergeTypes(errorInfo*, Hjava_lang_Class* this,
+				     Type* t1, Type* t2);
+extern Hjava_lang_Class*  getCommonSuperclass(Hjava_lang_Class* t1,
+					      Hjava_lang_Class* t2);
+
+extern bool typecheck(errorInfo*, Hjava_lang_Class* this, Type* t1, Type* t2);
+
+#endif /* !defined(VERIFY_TYPE_H) */
Index: kaffe/kaffe/kaffevm/verify-uninit.h
diff -u kaffe/kaffe/kaffevm/verify-uninit.h:1.2 kaffe/kaffe/kaffevm/verify-uninit.h:1.3
--- kaffe/kaffe/kaffevm/verify-uninit.h:1.2	Tue Mar  2 17:48:47 2004
+++ kaffe/kaffe/kaffevm/verify-uninit.h	Fri Mar  5 13:45:31 2004
@@ -13,7 +13,7 @@
 #if !defined(VERIFY_UNINIT_H)
 #define VERIFY_UNINIT_H
 
-#include "verify.h"
+#include "verify-type.h"
 #include "verify-block.h"

*** Patch too long, truncated ***




More information about the kaffe mailing list