From: bdemsky Date: Sun, 7 Mar 2004 22:00:14 +0000 (+0000) Subject: Added: X-Git-Url: http://plrg.eecs.uci.edu/git/?p=repair.git;a=commitdiff_plain;h=445c4854d296285d0ed336f8cb9002ab2e3e75bc Added: 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... --- diff --git a/Repair/RepairCompiler/MCC/IR/DotExpr.java b/Repair/RepairCompiler/MCC/IR/DotExpr.java index c7ed42f..7924bb4 100755 --- a/Repair/RepairCompiler/MCC/IR/DotExpr.java +++ b/Repair/RepairCompiler/MCC/IR/DotExpr.java @@ -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) { diff --git a/Repair/RepairCompiler/MCC/IR/LogicStatement.java b/Repair/RepairCompiler/MCC/IR/LogicStatement.java index 5871004..ab23ec3 100755 --- a/Repair/RepairCompiler/MCC/IR/LogicStatement.java +++ b/Repair/RepairCompiler/MCC/IR/LogicStatement.java @@ -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) */ diff --git a/Repair/RepairCompiler/MCC/IR/OpExpr.java b/Repair/RepairCompiler/MCC/IR/OpExpr.java index 7a256bd..e9b3f59 100755 --- a/Repair/RepairCompiler/MCC/IR/OpExpr.java +++ b/Repair/RepairCompiler/MCC/IR/OpExpr.java @@ -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() + ";"); } } diff --git a/Repair/RepairCompiler/MCC/IR/RepairGenerator.java b/Repair/RepairCompiler/MCC/IR/RepairGenerator.java index db37cde..82af1ba 100755 --- a/Repair/RepairCompiler/MCC/IR/RepairGenerator.java +++ b/Repair/RepairCompiler/MCC/IR/RepairGenerator.java @@ -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"); crhead.outputline("#include "); 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;jcomputesizes(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