start of new file
[IRC.git] / Robust / src / IR / TypeUtil.java
index da25f219da1321803eabcfe91cf3f96302983ca5..92e4e5861b45b6483e7a1dedf14b70ef882ff5df 100644 (file)
@@ -5,6 +5,8 @@ public class TypeUtil {
     public static final String StringClass="String";
     public static final String ObjectClass="Object";
     public static final String StartupClass="StartupObject";
+    public static final String TagClass="TagDescriptor";
+    public static final String ThreadClass="Thread";
     State state;
     Hashtable supertable;
     Hashtable subclasstable;
@@ -28,11 +30,103 @@ public class TypeUtil {
            String superc=cd.getSuper();
            if (superc!=null) {
                ClassDescriptor cd_super=getClass(superc);
+               if (cd_super==null) {
+                   throw new Error("Couldn't find class:"+superc);
+               }
                supertable.put(cd,cd_super);
            }
        }
     }
 
+    public ClassDescriptor getMainClass() {
+       return getClass(state.main);
+    }
+
+    public MethodDescriptor getRun() {
+       ClassDescriptor cd=getClass(TypeUtil.ThreadClass);
+       for(Iterator methodit=cd.getMethodTable().getSet("run").iterator();methodit.hasNext();) {
+           MethodDescriptor md=(MethodDescriptor) methodit.next();
+           if (md.numParameters()!=0||md.getModifiers().isStatic())
+               continue;
+           return md;
+       }
+       throw new Error("Can't find Thread.run");
+    }
+
+    public MethodDescriptor getMain() {
+       ClassDescriptor cd=getMainClass();
+       Set mainset=cd.getMethodTable().getSet("main");
+       for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
+           MethodDescriptor md=(MethodDescriptor)mainit.next();
+           if (md.numParameters()!=1)
+               continue;
+           Descriptor pd=md.getParameter(0);
+           TypeDescriptor tpd=(pd instanceof TagVarDescriptor)?((TagVarDescriptor)pd).getType():((VarDescriptor)pd)
+               .getType();
+           if (tpd.getArrayCount()!=1)
+               continue;
+           if (!tpd.getSymbol().equals("String"))
+               continue;
+           
+           if (!md.getModifiers().isStatic())
+               throw new Error("Error: Non static main");
+           return md;
+       }
+       throw new Error(cd+" has no main");
+    }
+
+    /** Check to see if md1 is more specific than md2...  Informally
+       if md2 could always be called given the arguments passed into
+       md1 */
+
+    public boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) {
+       /* Checks if md1 is more specific than md2 */
+       if (md1.numParameters()!=md2.numParameters())
+           throw new Error();
+       for(int i=0;i<md1.numParameters();i++) {
+           if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
+               return false;
+       }
+       if (!this.isSuperorType(md2.getReturnType(), md1.getReturnType()))
+               return false;
+
+       if (!this.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
+               return false;
+
+       return true;
+    }
+
+    public MethodDescriptor getMethod(ClassDescriptor cd, String name, TypeDescriptor[] types) {
+       Set methoddescriptorset=cd.getMethodTable().getSet(name);
+        MethodDescriptor bestmd=null;
+        NextMethod:
+        for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
+            MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+            /* Need correct number of parameters */
+            if (types.length!=currmd.numParameters())
+                continue;
+            for(int i=0;i<types.length;i++) {
+                if (!this.isSuperorType(currmd.getParamType(i),types[i]))
+                    continue NextMethod;
+            }
+            /* Method okay so far */
+            if (bestmd==null)
+                bestmd=currmd;
+            else {
+                if (isMoreSpecific(currmd,bestmd)) {
+                    bestmd=currmd;
+                } else if (!isMoreSpecific(bestmd, currmd))
+                    throw new Error("No method is most specific");
+                
+                /* Is this more specific than bestmd */
+            }
+        }
+       if (bestmd==null)
+           throw new Error("Could find: "+name + " in "+cd);
+
+       return bestmd;
+    }
+
     public void createFullTable() {
        subclasstable=new Hashtable();
     
@@ -82,6 +176,10 @@ public class TypeUtil {
        if (possiblesuper.equals(cd2))
            return true;
 
+       if ((possiblesuper.isTag() && !cd2.isTag())||
+           (!possiblesuper.isTag() && cd2.isTag()))
+           return false;
+
        //Handle arrays
        if (cd2.isArray()||possiblesuper.isArray()) {
            // Object is super class of all arrays
@@ -141,17 +239,17 @@ public class TypeUtil {
            
            return false;
        } else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
-                  (cd2.isArray()||cd2.isPtr()))
+                  cd2.isPtr())
            return false;
        else if (cd2.isPrimitive()&&(!cd2.isArray())&&
-                (possiblesuper.isArray()||possiblesuper.isPtr()))
+                possiblesuper.isPtr())
            return false;
        else
-           throw new Error();
+           throw new Error("Case not handled:"+possiblesuper+" "+cd2);
     }
 
-
-    private boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+    
+    public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
        if (possiblesuper==cd2)
            return true;
        else