[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