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 <[EMAIL PROTECTED]>

        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 <[EMAIL PROTECTED]>
+
+        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 <[EMAIL PROTECTED]>
 
         * 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 \
[EMAIL PROTECTED]@      ./$(DEPDIR)/verify-type.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/verify-uninit.Plo \
[EMAIL PROTECTED]@      ./$(DEPDIR)/verify.Plo
[EMAIL PROTECTED]@      ./$(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@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
[EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
[EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 
 .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 ***

_______________________________________________
kaffe mailing list
[EMAIL PROTECTED]
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to