Added:
authorbdemsky <bdemsky>
Sun, 7 Mar 2004 22:00:14 +0000 (22:00 +0000)
committerbdemsky <bdemsky>
Sun, 7 Mar 2004 22:00:14 +0000 (22:00 +0000)
3 value logic for Expr's...This will break dan's stuff, but arguably
it is the first step in fixing his stuff...

Runtime support for checking type sanity/etc...

Repair/RepairCompiler/MCC/IR/DotExpr.java
Repair/RepairCompiler/MCC/IR/LogicStatement.java
Repair/RepairCompiler/MCC/IR/OpExpr.java
Repair/RepairCompiler/MCC/IR/RepairGenerator.java
Repair/RepairCompiler/MCC/IR/ReservedTypeDescriptor.java
Repair/RepairCompiler/MCC/IR/SemanticChecker.java
Repair/RepairCompiler/MCC/IR/StructureGenerator.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/StructureTypeDescriptor.java
Repair/RepairCompiler/MCC/IR/TypeDescriptor.java
Repair/RepairCompiler/MCC/IR/VarDescriptor.java
Repair/RepairCompiler/MCC/IR/VarExpr.java

index c7ed42f..7924bb4 100755 (executable)
@@ -7,6 +7,10 @@ public class DotExpr extends Expr {
     Expr left;
     String field;
     Expr index;
+    
+    static boolean DOMEMCHECKS=true;
+    static boolean DOTYPECHECKS=false;
+    static boolean DONULL=false;
 
     public Set freeVars() {
        Set lset=left.freeVars();
@@ -106,7 +110,7 @@ public class DotExpr extends Expr {
         left.prettyPrint(writer);
         writer.outputline("");
       
-        StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();        
+        StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
         Expr intindex = index;
         Expr offsetbits;
 
@@ -142,16 +146,6 @@ public class DotExpr extends Expr {
             throw new IRException();
         }
                
-        // #TBD#: ptr's to bits and byte's and stuff are a little iffy... 
-        // right now, a bit* is the same as a int* = short* = byte* (that is there 
-        // is no post-derefernce mask)
-        
-        // #ATTN#: do we handle int* correctly? what is the correct behavior? we automatically 
-        // dereference pointers, but for structures that means that if we have a nested structure
-        // we return an integer address to that nested structure. if we have a pointer to a 
-        // structure else where we want that base address ... yeah so we *(int *) it... ok we are
-        // correct
-
         boolean dotypecheck = false;
 
         if (offsetbits instanceof IntegerLiteralExpr) {
@@ -163,20 +157,35 @@ public class DotExpr extends Expr {
                 int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
                                
                 /* type var = ((*(int *) (base + offset)) >> shift) & mask */
-                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
-                                  " = ((*(int *)" + 
+               writer.outputline(getType().getGenerateType() + " "+dest.getSafeSymbol()+"=0;");
+               writer.outputline("if ("+leftd.getSafeSymbol()+")");
+               writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" + 
                                   "(" + leftd.getSafeSymbol() + " + " + offset + ")) " + 
-                                  " >> " + shift + ") & 0x" + Integer.toHexString(mask) + ";");  
+                                  " >> " + shift + ") & 0x" + Integer.toHexString(mask) + ";");
+               writer.outputline("else maybe=1;");
             } else { /* a structure address or a ptr! */
                 String ptr = fd.getPtr() ? "*(int *)" : "";
                 /* type var = [*(int *)] (base + offset) */
-
-                // #ATTN: was 'getType.getGeneratedType()' instead of 'int' but all pointers are represented
-                // by integers
-                writer.outputline("int " + dest.getSafeSymbol() + 
+                writer.outputline("int " + dest.getSafeSymbol()+"=0;");
+               writer.outputline("if ("+leftd.getSafeSymbol()+")");
+                writer.outputline(dest.getSafeSymbol() + 
                                   " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ");");  
-
-                dotypecheck = true;
+               writer.outputline("else maybe=1;");
+               if (fd.getPtr()) {
+                   VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+                   if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
+                       writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+                       dotypecheck = true;
+                   } else if (DOTYPECHECKS) {
+                       writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+                   }
+                   writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+                   writer.startblock();
+                   writer.outputline(dest.getSafeSymbol()+"=0;");
+                   if (DONULL)
+                       writer.outputline(ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ")=0;");
+                   writer.endblock();
+               }
             }
         } else { /* offset in bits is an expression that must be generated */                        
             VarDescriptor ob = VarDescriptor.makeNew("offsetinbits");
@@ -199,48 +208,38 @@ public class DotExpr extends Expr {
                 int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
                 
                 /* type var = ((*(int *) (base + offset)) >> shift) & mask */
-                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
+               writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol()+"=0;");
+               writer.outputline("if ("+leftd.getSafeSymbol()+")");
+                writer.outputline(dest.getSafeSymbol() + 
                                   " = ((*(int *)" + 
                                   "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " + 
                                   " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");  
+               writer.outputline("else maybe=1;");
             } else { /* a structure address or a ptr */
                 String ptr = fd.getPtr() ? "*(int *)" : "";
                 /* type var = [*(int *)] (base + offset) */
-
-                // #ATTN: was 'getType.getGeneratedType()' instead of 'int' but all pointers are represented
-                // by integers
-                writer.outputline("int " + dest.getSafeSymbol() + 
+                writer.outputline("int " + dest.getSafeSymbol() +"=0;"); 
+               writer.outputline("if ("+leftd.getSafeSymbol()+")");
+                writer.outputline(dest.getSafeSymbol() + 
                                   " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");  
-                dotypecheck = true;
+               writer.outputline("else maybe=1;");
+               if (fd.getPtr()) {
+                   VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+                   if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
+                       writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+                       dotypecheck = true;
+                   } else if (DOTYPECHECKS) {
+                       writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+                   }
+                   writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+                   writer.startblock();
+                   writer.outputline(dest.getSafeSymbol()+"=0;");
+                   if (DONULL)
+                       writer.outputline(ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")=0;");
+                   writer.endblock();
+               }
             }
         }
-
-
-        if (dotypecheck) { /* typemap checks! */
-            // dest is 'low'
-            // high is 'low' + sizeof(fd.getDataStructure) <<< can be cached!!
-
-            // #ATTN#: we need to get the size of the fieldtype (if its a label the type of the label, not the 
-            // underlying field's type
-
-            Expr sizeofexpr = fieldtype.getSizeExpr();
-            VarDescriptor sizeof = VarDescriptor.makeNew("sizeof");
-            sizeofexpr.generate(writer, sizeof);
-
-            String low = dest.getSafeSymbol();
-            String high = VarDescriptor.makeNew("high").getSafeSymbol();
-            writer.outputline("int " + high + " = " + low + " + " + sizeof.getSafeSymbol() + ";");            
-            writer.outputline("assertvalidmemory(" + low + ", " + high + ");");            
-
-            // we need to null value check and conditionalize the rest of the rule... we'll use a hack
-            // here where we store the number of indents in this class... and then provide a static 
-            // method to unwind...
-            //writer.outputline("// assertvalidmemory ");
-            //DotExpr.memoryindents++;
-            //writer.outputline("if (" + dest.getSafeSymbol() + " != NULL)");
-            //writer.startblock();           
-        }
-
     }
 
     private int bitmask(int bits) {
index 5871004..ab23ec3 100755 (executable)
@@ -98,7 +98,7 @@ public class LogicStatement {
             left.generate(writer, leftd);
 
             writer.outputline("// 3-valued NOT");
-            writer.outputline("if (!maybe)");
+           //            writer.outputline("if (!maybe)"); //this isn't really necessary
             writer.startblock();
             writer.outputline(dest.getSafeSymbol() + " =  !" + leftd.getSafeSymbol() + ";");
             writer.endblock();
@@ -109,7 +109,7 @@ public class LogicStatement {
             String lm = (VarDescriptor.makeNew("leftmaybe")).getSafeSymbol();
             left.generate(writer, leftd);
             writer.outputline("int " + lm + " = maybe;");
-            
+            writer.outputline("maybe=0;");
             VarDescriptor rightd = VarDescriptor.makeNew("rightboolean");
             String rm = (VarDescriptor.makeNew("rightmaybe")).getSafeSymbol();
             assert right != null;
@@ -144,7 +144,7 @@ public class LogicStatement {
                  * 1110  1 X
                  * 1111  1 X
                  *
-                 * M = (L*RM) + (R*LM) + (LM*RM)                 
+                 * M = (L*RM) + (R*LM) + (LM*RM)
                  * O = (L*R)
                  */
                
index 7a256bd..e9b3f59 100755 (executable)
@@ -235,8 +235,16 @@ public class OpExpr extends Expr {
         VarDescriptor ld = VarDescriptor.makeNew("leftop");
         left.generate(writer, ld);        
         VarDescriptor rd = null;
+       VarDescriptor lm=VarDescriptor.makeNew("lm");
+       VarDescriptor rm=VarDescriptor.makeNew("rm");
 
         if (right != null) {
+           if ((opcode==Opcode.OR)||
+               (opcode==Opcode.AND)) {
+               writer.outputline("int "+lm.getSafeSymbol()+"=maybe;");
+               writer.outputline("int maybe=0;");
+           }
+
             rd = VarDescriptor.makeNew("rightop");
             right.generate(writer, rd);
         }
@@ -253,7 +261,17 @@ public class OpExpr extends Expr {
             assert rd != null;
             writer.outputline("int " + dest.getSafeSymbol() + " = " + 
                               ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
-        } else {
+        } else if (opcode == Opcode.AND) {
+           writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+           writer.outputline("maybe = (" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (" + rd.getSafeSymbol() + " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
+           writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " && " + rd.getSafeSymbol() + ";");
+       } else if (opcode == Opcode.OR) {
+           writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+           writer.outputline("maybe = (!" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (!" + rd.getSafeSymbol() +
+                             " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
+           writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() +
+                             ";");
+       } else {
             writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
         }
     }
index db37cde..82af1ba 100755 (executable)
@@ -36,12 +36,26 @@ public class RepairGenerator {
         togenerate.addAll(termination.conjunctions);
         togenerate.removeAll(removed);
         GraphNode.computeclosure(togenerate,removed);
-
        cost=new Cost();
        sources=new Sources(state);
        Repair.repairgenerator=this;
     }
 
+    private void generatetypechecks(boolean flag) {
+       if (flag) {
+           DotExpr.DOTYPECHECKS=true;
+           VarExpr.DOTYPECHECKS=true;
+           DotExpr.DONULL=true;
+           VarExpr.DONULL=true;
+       } else {
+           VarExpr.DOTYPECHECKS=false;
+           DotExpr.DOTYPECHECKS=false;
+           VarExpr.DONULL=true;
+           DotExpr.DONULL=true;
+       }
+    }
+
+
     private void name_updates() {
        int count=0;
        for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
@@ -63,7 +77,7 @@ public class RepairGenerator {
         this.outputhead = new java.io.PrintWriter(outputhead, true);
         headername=st;
        name_updates();
-
+       generatetypechecks(true);
         generate_tokentable();
         generate_hashtables();
        generate_stateobject();
@@ -76,7 +90,15 @@ public class RepairGenerator {
        CodeWriter craux = new StandardCodeWriter(this.outputaux);
        crhead.outputline("};");
        craux.outputline("}");
+       generatetypechecks(false);
+       generate_computesizes();
+       generatetypechecks(true);
+       generate_recomputesizes();
+       generatetypechecks(false);
        generate_updates();
+       StructureGenerator sg=new StructureGenerator(state,this);
+       sg.buildall();
+       crhead.outputline("#endif");
     }
 
     String ststate="state";
@@ -117,11 +139,13 @@ public class RepairGenerator {
                        craux.outputline("void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+")");
                    }
                    craux.startblock();
+                   craux.outputline("int maybe=0;");
                    final SymbolTable st = un.getRule().getSymbolTable();                
                    CodeWriter cr = new StandardCodeWriter(outputaux) {
                         public SymbolTable getSymbolTable() { return st; }
                     };
                    un.generate(cr, false, stleft,stright,this);
+                   craux.outputline("if (maybe) printf(\"REALLY BAD\");");
                    craux.endblock();
                    break;
                case MultUpdateNode.REMOVE:
@@ -146,11 +170,13 @@ public class RepairGenerator {
                    crhead.outputline(methodcall+";");
                    craux.outputline(methodcall);
                    craux.startblock();
+                   craux.outputline("int maybe=0;");
                    final SymbolTable st2 = un.getRule().getSymbolTable();                
                    CodeWriter cr2 = new StandardCodeWriter(outputaux) {
                         public SymbolTable getSymbolTable() { return st2; }
                     };
                    un.generate(cr2, true, null,null,this);
+                   craux.outputline("if (maybe) printf(\"REALLY BAD\");");
                    craux.endblock();
                    break;
                case MultUpdateNode.MODIFY:
@@ -206,12 +232,88 @@ public class RepairGenerator {
            VarDescriptor vd=(VarDescriptor) globals.next();
            crhead.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+";");
        }
+       crhead.outputline("void computesizes(int *,int **);");
+       crhead.outputline("void recomputesizes();");
+    }
+
+    private void generate_computesizes() {
+       int max=TypeDescriptor.counter;
+       TypeDescriptor[] tdarray=new TypeDescriptor[max];
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           tdarray[ttd.getId()]=ttd;
+       }
+       CodeWriter cr=new StandardCodeWriter(outputaux);
+       cr.outputline("void "+name+"_state::computesizes(int *sizearray,int **numele) {");
+       for(int i=0;i<max;i++) {
+           TypeDescriptor td=tdarray[i];
+           Expr size=td.getSizeExpr();
+           VarDescriptor vd=VarDescriptor.makeNew("size");
+           size.generate(cr,vd);
+           cr.outputline("sizearray["+i+"]="+vd.getSafeSymbol()+";");
+       }
+       for(int i=0;i<max;i++) {
+           TypeDescriptor td=tdarray[i];
+           if (td instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) td;
+               for(int j=0;j<std.fieldlist.size();j++) {
+                   FieldDescriptor fd=(FieldDescriptor)std.fieldlist.get(j);
+                   if (fd instanceof ArrayDescriptor) {
+                       ArrayDescriptor ad=(ArrayDescriptor)fd;
+                       Expr index=ad.getIndexBound();
+                       VarDescriptor vd=VarDescriptor.makeNew("index");
+                       index.generate(cr,vd);
+                       cr.outputline("numele["+i+"]["+j+"]="+vd.getSafeSymbol()+";");
+                   }
+               }
+           }
+       }
+       cr.outputline("}");
     }
 
+    private void generate_recomputesizes() {
+       int max=TypeDescriptor.counter;
+       TypeDescriptor[] tdarray=new TypeDescriptor[max];
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           tdarray[ttd.getId()]=ttd;
+       }
+       CodeWriter cr=new StandardCodeWriter(outputaux);
+       cr.outputline("void "+name+"_state::recomputesizes() {");
+       for(int i=0;i<max;i++) {
+           TypeDescriptor td=tdarray[i];
+           Expr size=td.getSizeExpr();
+           VarDescriptor vd=VarDescriptor.makeNew("size");
+           size.generate(cr,vd);
+       }
+       for(int i=0;i<max;i++) {
+           TypeDescriptor td=tdarray[i];
+           if (td instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) td;
+               for(int j=0;j<std.fieldlist.size();j++) {
+                   FieldDescriptor fd=(FieldDescriptor)std.fieldlist.get(j);
+                   if (fd instanceof ArrayDescriptor) {
+                       ArrayDescriptor ad=(ArrayDescriptor)fd;
+                       Expr index=ad.getIndexBound();
+                       VarDescriptor vd=VarDescriptor.makeNew("index");
+                       index.generate(cr,vd);
+                   }
+               }
+           }
+       }
+       cr.outputline("}");
+    }
+
+
     private void generate_hashtables() {
         CodeWriter craux = new StandardCodeWriter(outputaux);
         CodeWriter crhead = new StandardCodeWriter(outputhead);
+       crhead.outputline("#ifndef "+name+"_h");
+       crhead.outputline("#define "+name+"_h");
         crhead.outputline("#include \"SimpleHash.h\"");
+       crhead.outputline("extern \"C\" {");
+        crhead.outputline("#include \"instrument.h\"");
+       crhead.outputline("}");
         crhead.outputline("#include <stdio.h>");
         crhead.outputline("#include <stdlib.h>");
        crhead.outputline("class "+name+" {");
@@ -219,6 +321,7 @@ public class RepairGenerator {
        crhead.outputline(name+"();");
        crhead.outputline("~"+name+"();");
         craux.outputline("#include \""+headername+"\"");
+        craux.outputline("#include \"size.h\"");
 
         craux.outputline(name+"::"+name+"() {");
         craux.outputline("// creating hashtables ");
@@ -306,7 +409,10 @@ public class RepairGenerator {
        repairtable=VarDescriptor.makeNew("repairtable");
        crhead.outputline("void doanalysis();");
        craux.outputline("void "+name +"_state::doanalysis()");
-       craux.startblock();
+       craux.startblock();
+       craux.outputline("typeobject *typeobject1=gettypeobject();");
+       craux.outputline("typeobject1->computesizes(this);");
+       craux.outputline("recomputesizes();");
        craux.outputline(name+ " * "+oldmodel.getSafeSymbol()+"=0;");
         craux.outputline("WorkList * "+worklist.getSafeSymbol()+" = new WorkList();");
        craux.outputline("RepairHash * "+repairtable.getSafeSymbol()+"=0;");
@@ -360,12 +466,13 @@ public class RepairGenerator {
                     };
                cr.outputline("// build " +escape(rule.toString()));
                 cr.startblock();
+               cr.outputline("int maybe=0;");
                 ListIterator quantifiers = rule.quantifiers();
                 while (quantifiers.hasNext()) {
                     Quantifier quantifier = (Quantifier) quantifiers.next();
                     quantifier.generate_open(cr);
                 }
-                        
+
                 /* pretty print! */
                 cr.output("//");
                 rule.getGuardExpr().prettyPrint(cr);
@@ -415,6 +522,7 @@ public class RepairGenerator {
                 cr.indent();
                 cr.outputline(elseladder + " ("+idvar.getSafeSymbol()+" == " + dispatchid + ")");
                 cr.startblock();
+               cr.outputline("int maybe=0;");
                VarDescriptor typevar=VarDescriptor.makeNew("type");
                VarDescriptor leftvar=VarDescriptor.makeNew("left");
                VarDescriptor rightvar=VarDescriptor.makeNew("right");
@@ -586,7 +694,8 @@ public class RepairGenerator {
                cr.outputline("switch("+mincostindex.getSafeSymbol()+") {");
                for(int j=0;j<dnfconst.size();j++) {
                    Conjunction conj=dnfconst.get(j);
-                   GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj);                    if (removed.contains(gn))
+                   GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj);
+                   if (removed.contains(gn))
                        continue;
                    cr.outputline("case "+j+":");
                    for(int k=0;k<conj.size();k++) {
@@ -612,7 +721,6 @@ public class RepairGenerator {
                        cr.endblock();
                    }
                    /* Update model */
-                   
                    cr.outputline("break;");
                }
                cr.outputline("}");
@@ -637,6 +745,7 @@ public class RepairGenerator {
                cr.outputline("delete "+oldmodel.getSafeSymbol()+";");
                cr.outputline("delete "+newmodel.getSafeSymbol()+";");
                cr.outputline("delete "+worklist.getSafeSymbol()+";");
+               cr.outputline("resettypemap();");
                cr.outputline("break;");
                cr.endblock();
                cr.outputline("rebuild:");
@@ -646,7 +755,7 @@ public class RepairGenerator {
                 cr.outputline("");
             }
         }
-    }    
+    }
     
     private MultUpdateNode getmultupdatenode(Conjunction conj, DNFPredicate dpred, int repairtype) {
        MultUpdateNode mun=null;
@@ -1347,6 +1456,3 @@ public class RepairGenerator {
        cr.endblock();
     }
 }
-
-
-
index a02dd31..6068fcf 100755 (executable)
@@ -27,5 +27,4 @@ public class ReservedTypeDescriptor extends TypeDescriptor {
     public String getSafeSymbol() {
         return getSymbol();
     }
-
 }
index 46e0105..fb3f020 100755 (executable)
@@ -1014,7 +1014,7 @@ public class SemanticChecker {
             return false;
         }
 
-        stGlobals.add(new VarDescriptor(name, name, td));
+        stGlobals.add(new VarDescriptor(name, name, td,true));
         return true;
     }
 
diff --git a/Repair/RepairCompiler/MCC/IR/StructureGenerator.java b/Repair/RepairCompiler/MCC/IR/StructureGenerator.java
new file mode 100755 (executable)
index 0000000..fe8e4b1
--- /dev/null
@@ -0,0 +1,259 @@
+package MCC.IR;
+
+import java.io.*;
+import java.util.*;
+import MCC.State;
+
+public class StructureGenerator {
+    State state;
+    CodeWriter cr;
+    CodeWriter crhead;
+    TypeDescriptor[] tdarray;
+    RepairGenerator rg;
+    StructureGenerator(State state, RepairGenerator rg) {
+       this.state=state;
+       this.rg=rg;
+       try {
+           cr=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.cc"),true));
+           crhead=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.h"),true));
+       } catch (Exception e) {
+           e.printStackTrace();
+       }
+    }
+
+    void buildall() {
+       int max=TypeDescriptor.counter;
+       tdarray=new TypeDescriptor[max];
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           tdarray[ttd.getId()]=ttd;
+       }
+       cr.outputline("#include \"size.h\"");
+       generategetfield();
+       generategetnumfields();
+       generateisArray();
+       generateisPtr();
+       generateissubtype();
+       generatecalls();
+       generatecomputesize();
+       generateheader();
+    }
+
+    private void generatecalls() {
+       int max=TypeDescriptor.counter;
+       cr.outputline("int arsize["+max+"];");
+
+       for(int i=0;i<max;i++) {
+           TypeDescriptor ttd=tdarray[i];
+           if (ttd instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+               String str="int arnumelement"+std.getId()+"["+std.fieldlist.size()+"]={";
+               for(int j=0;j<std.fieldlist.size();j++) {
+                   str+=0;
+                   if (((j+1)!=std.fieldlist.size()))
+                       str+=",";
+               }
+               str+="};";
+               cr.outputline(str);
+           } else
+               cr.outputline("int arnumelement"+ttd.getId()+"[0];");
+       }
+       String str="int* arnumelements["+String.valueOf(max)+"]={";
+       for(int i=0;i<max;i++) {
+           str+="arnumelement"+i;
+           if (((i+1)!=max))
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       
+
+       cr.outputline("int typeobject::size(int type) {");
+       cr.outputline("return arsize[type];");
+       cr.outputline("}");
+
+       cr.outputline("int typeobject::numElements(int type, int fieldindex) {");
+       cr.outputline("return arnumelements[type][fieldindex];");
+       cr.outputline("}");
+       cr.outputline("typeobject::typeobject() {}");
+    }
+
+    private void generatecomputesize() {
+       int max=TypeDescriptor.counter;
+       cr.outputline("void typeobject::computesizes("+rg.name+"_state * obj) {");
+       cr.outputline("obj->computesizes(arsize,arnumelements);");
+       cr.outputline("}");
+    }
+
+    private void generateheader() {
+       crhead.outputline("#include \""+rg.headername + "\"");
+       crhead.outputline("class typeobject {");
+       crhead.outputline("public:");
+       crhead.outputline("typeobject();");
+       crhead.outputline("int getfield(int type, int fieldindex);");
+       crhead.outputline("int isArray(int type, int fieldindex);");
+       crhead.outputline("int isPtr(int type, int fieldindex);");
+       crhead.outputline("int numElements(int type, int fieldindex);");
+       crhead.outputline("int size(int type);");
+       crhead.outputline("int getnumfields(int type);");
+       crhead.outputline("bool issubtype(int subtype, int type);");
+       crhead.outputline("void computesizes("+rg.name+"_state *);");
+       crhead.outputline("};");
+    }
+
+    
+    private void generategetfield() {
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           String str="";
+
+           if (ttd instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+               str="int argetfield"+std.getId()+"["+std.fieldlist.size()+"]={";
+               for(int i=0;i<std.fieldlist.size();i++) {
+                   FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+                   TypeDescriptor td = fd.getType();
+                   str+=String.valueOf(td.getId());
+                   if ((i+1)!=std.fieldlist.size())
+                       str+=",";
+               }
+               str+="};";
+               cr.outputline(str);
+           } else
+               cr.outputline("int argetfield"+ttd.getId()+"[0];");
+       }
+       int max=TypeDescriptor.counter;
+       String str="int* argetfield["+String.valueOf(max)+"]={";
+       for(int i=0;i<max;i++) {
+           str+="argetfield"+i;
+           if (((i+1)!=max))
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       
+       cr.outputline("int typeobject::getfield(int type, int fieldindex) {");
+       cr.outputline("return argetfield[type][fieldindex];");
+       cr.outputline("}");
+    }
+
+   private void generategetnumfields() {
+       int max=TypeDescriptor.counter;
+       String str="int argetnumfield["+String.valueOf(max)+"]={";
+       for(int i=0;i<max;i++) {
+           TypeDescriptor ttd=tdarray[i];
+           if (ttd instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+               str+=String.valueOf(std.fieldlist.size());
+           } else
+               str+="0";
+           if (((i+1)!=max))
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       
+       cr.outputline("int typeobject::getnumfields(int type) {");
+       cr.outputline("return argetnumfield[type];");
+       cr.outputline("}");
+    }
+    private void generateisArray() {
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           String str="";
+
+           if (ttd instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+               str="int arisArray"+std.getId()+"["+std.fieldlist.size()+"]={";
+               for(int i=0;i<std.fieldlist.size();i++) {
+                   FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+                   TypeDescriptor td = fd.getType();
+                   if (fd instanceof ArrayDescriptor)
+                       str+="1";
+                   else
+                       str+="0";
+                   if ((i+1)!=std.fieldlist.size())
+                       str+=",";
+               }
+               str+="};";
+               cr.outputline(str);
+           } else
+               cr.outputline("int arisArray"+ttd.getId()+"[0];");
+       }
+       int max=TypeDescriptor.counter;
+       String str="int* arisArray["+String.valueOf(max)+"]={";
+       for(int i=0;i<max;i++) {
+           str+="arisArray"+i;
+           if (((i+1)!=max))
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       
+       cr.outputline("int typeobject::isArray(int type, int fieldindex) {");
+       cr.outputline("return arisArray[type][fieldindex];");
+       cr.outputline("}");
+    }
+    private void generateisPtr() {
+       for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+           TypeDescriptor ttd=(TypeDescriptor)it.next();
+           String str="";
+
+           if (ttd instanceof StructureTypeDescriptor) {
+               StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+               str="int arisPtr"+std.getId()+"["+std.fieldlist.size()+"]={";
+               for(int i=0;i<std.fieldlist.size();i++) {
+                   FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+                   if (fd.getPtr())
+                       str+="1";
+                   else
+                       str+="0";
+                   if ((i+1)!=std.fieldlist.size())
+                       str+=",";
+               }
+               str+="};";
+               cr.outputline(str);
+           } else
+               cr.outputline("int arisPtr"+ttd.getId()+"[0];");
+       }
+       int max=TypeDescriptor.counter;
+       String str="int* arisPtr["+String.valueOf(max)+"]={";
+       for(int i=0;i<max;i++) {
+           str+="arisPtr"+i;
+           if (((i+1)!=max))
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       
+       cr.outputline("int typeobject::isPtr(int type, int fieldindex) {");
+       cr.outputline("return arisPtr[type][fieldindex];");
+       cr.outputline("}");
+    }
+
+    void generateissubtype() {
+       int max=TypeDescriptor.counter;
+       String str="bool arissubtype["+max+"]["+max+"]={";
+       for(int i=0;i<max;i++) {
+           str+="{";
+           for(int j=0;j<max;j++) {
+               TypeDescriptor tdi=tdarray[i];
+               TypeDescriptor tdj=tdarray[j];
+               if (tdi.isSubtypeOf(tdj))
+                   str+="1";
+               else
+                   str+="0";
+               if ((j+1)!=max)
+                   str+=",";
+           }
+           str+="}";
+           if ((i+1)!=max)
+               str+=",";
+       }
+       str+="};";
+       cr.outputline(str);
+       cr.outputline("bool typeobject::issubtype(int subtype, int type) {");
+       cr.outputline("return arissubtype[subtype][type];");
+       cr.outputline("}");
+    }
+}
index 7b6e514..f0808e8 100755 (executable)
@@ -15,16 +15,10 @@ public class StructureTypeDescriptor extends TypeDescriptor {
     Hashtable fields = new Hashtable(); /* fast lookups */
     Vector fieldlist = new Vector(); /* ordering information */
     Hashtable labels = new Hashtable();
-    int idnum;
-    static int counter=0;
 
-    public int getId() {
-       return idnum;
-    }
 
     public StructureTypeDescriptor(String name) {
         super(name);
-       idnum=counter++;
     }
 
     public TypeDescriptor getGenerateType() {
@@ -139,6 +133,8 @@ public class StructureTypeDescriptor extends TypeDescriptor {
         if (td == this) {
             return true;
         } else {
+           if (subtype==null)
+               return false;
             return subtype.isSubtypeOf(td);
         }
     }
index 5392f1b..f71fe4f 100755 (executable)
@@ -7,9 +7,17 @@ package MCC.IR;
  */
 
 public abstract class TypeDescriptor extends Descriptor {
+    static int counter=0;
+    int idnum;
+
+    public int getId() {
+       return idnum;
+    }
 
     public TypeDescriptor(String name) {
         super(name);
+       if (!(this instanceof MissingTypeDescriptor))
+           idnum=counter++;
     }
 
     public boolean isSubtypeOf(TypeDescriptor td) {
index 6fca9ce..f7f8722 100755 (executable)
@@ -3,6 +3,7 @@ package MCC.IR;
 public class VarDescriptor extends Descriptor {
     
     private static int count = 0;
+    boolean isglobal=false;
 
     TypeDescriptor td = null;
 
@@ -15,11 +16,16 @@ public class VarDescriptor extends Descriptor {
         this.td = td;
     }
 
-    public VarDescriptor(String name, String safename, TypeDescriptor td) {
+    public VarDescriptor(String name, String safename, TypeDescriptor td, boolean global) {
         super(name, safename);
         this.td = td;
+       this.isglobal=global;
     }
 
+    public boolean isGlobal() {
+       return isglobal;
+    }
+    
     public void setType(TypeDescriptor td) {
         this.td = td;
     }
index ff52366..2a71140 100755 (executable)
@@ -3,6 +3,9 @@ package MCC.IR;
 import java.util.*;
 
 public class VarExpr extends Expr {
+    static boolean DOMEMCHECKS=true;
+    static boolean DOTYPECHECKS=false;
+    static boolean DONULL=false;
 
     String varname;
     VarDescriptor vd = null;
@@ -75,8 +78,22 @@ public class VarExpr extends Expr {
         assert vd.getType() != null;
         this.td = vd.getType();
 
+
         writer.outputline(vd.getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + 
                           " = (" + vd.getType().getGenerateType().getSafeSymbol() + ") " + vd.getSafeSymbol() + "; //varexpr");
+       if (vd.isGlobal() && (DOTYPECHECKS||DOMEMCHECKS) && (td instanceof StructureTypeDescriptor)) {
+           VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+           if (DOTYPECHECKS)
+               writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + td.getId() + ");"); 
+           else
+               writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");"); 
+           writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+           writer.startblock();
+           writer.outputline(dest.getSafeSymbol()+"=0;");
+           if (DONULL)
+               writer.outputline(vd.getSafeSymbol()+"=0;");
+           writer.endblock();
+       }
     }
 
     public void prettyPrint(PrettyPrinter pp) {