Support for Virtual Calls
authorbdemsky <bdemsky>
Tue, 4 Apr 2006 23:35:19 +0000 (23:35 +0000)
committerbdemsky <bdemsky>
Tue, 4 Apr 2006 23:35:19 +0000 (23:35 +0000)
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/TypeUtil.java
Robust/src/Main/Main.java

index aee789840c1fb451e8ec0655da59de782fcaaff5..fd2eff59dec0410f02a5e0467d9613ac95752dee 100644 (file)
@@ -15,13 +15,16 @@ public class BuildCode {
     public static boolean GENERATEPRECISEGC=false;
     public static String PREFIX="";
     Virtual virtualcalls;
+    TypeUtil typeutil;
 
-    public BuildCode(State st, Hashtable temptovar) {
+
+    public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
        state=st;
        this.temptovar=temptovar;
        paramstable=new Hashtable();    
        tempstable=new Hashtable();
        fieldorder=new Hashtable();
+       this.typeutil=typeutil;
        virtualcalls=new Virtual(state);
     }
 
@@ -87,9 +90,10 @@ public class BuildCode {
        outmethod.close();
     }
 
+    private int maxcount=0;
+
     private void buildVirtualTables(PrintWriter outvirtual) {
        int numclasses=0;
-       int maxcount=0;
        Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
        while(classit.hasNext()) {
            ClassDescriptor cd=(ClassDescriptor)classit.next();
@@ -256,6 +260,7 @@ public class BuildCode {
                headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
                printcomma=true;
            }
+
            for(int i=0;i<objectparams.numPrimitives();i++) {
                TempDescriptor temp=objectparams.getPrimitive(i);
                if (printcomma)
@@ -443,10 +448,43 @@ public class BuildCode {
        }
        output.print("       ");
 
-       /* TODO: Virtual dispatch */
+
        if (fc.getReturnTemp()!=null)
            output.print(generateTemp(fm,fc.getReturnTemp())+"=");
-       output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+
+       if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
+           output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
+       } else {
+           
+           output.print("((");
+           if (md.getReturnType().isClass())
+               output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
+           else
+               output.print(md.getReturnType().getSafeSymbol()+" ");
+           output.print("(*)(");
+
+           boolean printcomma=false;
+           if (GENERATEPRECISEGC) {
+               output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
+               printcomma=true;
+           } 
+
+
+           for(int i=0;i<objectparams.numPrimitives();i++) {
+               TempDescriptor temp=objectparams.getPrimitive(i);
+               if (printcomma)
+                   output.print(", ");
+               printcomma=true;
+               if (temp.getType().isClass())
+                   output.print("struct " + temp.getType().getSafeSymbol()+" * ");
+               else
+                   output.print(temp.getType().getSafeSymbol());
+           }
+
+           output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
+       }
+
+       output.print("(");
        boolean needcomma=false;
        if (GENERATEPRECISEGC) {
            output.print("&__parameterlist__");
@@ -472,6 +510,22 @@ public class BuildCode {
        output.println("   }");
     }
 
+    private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
+       Set subclasses=typeutil.getSubClasses(thiscd);
+       if (subclasses==null)
+           return true;
+       for(Iterator classit=subclasses.iterator();classit.hasNext();) {
+           ClassDescriptor cd=(ClassDescriptor)classit.next();
+           Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
+           for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
+               MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+               if (md.matches(matchmd))
+                   return false;
+           }
+       }
+       return true;
+    }
+
     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
        output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
     }
@@ -548,7 +602,8 @@ public class BuildCode {
        if (GENERATEPRECISEGC) {
            output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
            printcomma=true;
-       }
+       } 
+
        for(int i=0;i<objectparams.numPrimitives();i++) {
            TempDescriptor temp=objectparams.getPrimitive(i);
            if (printcomma)
index 600ec9b937b2becdafc093674d1e51ec5df1e5fe..2cb7396803524c5d9ed4d1ba92c9fa08728b763e 100644 (file)
@@ -5,6 +5,7 @@ public class TypeUtil {
     public static final String StringClass="String";
     State state;
     Hashtable supertable;
+    Hashtable subclasstable;
 
     public TypeUtil(State state) {
        this.state=state;
@@ -18,6 +19,8 @@ public class TypeUtil {
 
     private void createTables() {
        supertable=new Hashtable();
+       subclasstable=new Hashtable();
+
        Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
        while(classit.hasNext()) {
            ClassDescriptor cd=(ClassDescriptor)classit.next();
@@ -26,9 +29,22 @@ public class TypeUtil {
                ClassDescriptor cd_super=getClass(superc);
                supertable.put(cd,cd_super);
            }
+           
+           ClassDescriptor tmp=cd.getSuperDesc();
+           while(tmp!=null) {
+               if (!subclasstable.containsKey(tmp))
+                   subclasstable.put(tmp,new HashSet());
+               HashSet hs=(HashSet)subclasstable.get(tmp);
+               hs.add(cd);
+               tmp=tmp.getSuperDesc();
+           }
        }
     }
 
+    public Set getSubClasses(ClassDescriptor cd) {
+       return (Set)subclasstable.get(cd);
+    }
+
     public ClassDescriptor getSuper(ClassDescriptor cd) {
        return (ClassDescriptor)supertable.get(cd);
     }
index a9200774cb7ce9f0bcf00a3d6dd5d90c0b2ade5f..51e69cccbcf6acf76891f6393c74eb85a6dc6ee8 100644 (file)
@@ -48,7 +48,7 @@ public class Main {
       BuildFlat bf=new BuildFlat(state);
       bf.buildFlat();
       
-      BuildCode bc=new BuildCode(state, bf.getMap());
+      BuildCode bc=new BuildCode(state, bf.getMap(), tu);
       bc.buildCode();
       
       System.exit(l.numErrors());