package MCC.IR;
import java.util.*;
+import MCC.State;
class UpdateNode {
Vector updates;
binding.put(b.getVar(),b);
}
+ public int numBindings() {
+ return bindings.size();
+ }
+
+ public Binding getBinding(int i) {
+ return (Binding)bindings.get(i);
+ }
+
public Binding getBinding(VarDescriptor vd) {
if (binding.containsKey(vd))
return (Binding)binding.get(vd);
public Updates getUpdate(int i) {
return (Updates)updates.get(i);
}
- public void generate(CodeWriter cr, boolean removal, String slot0, String slot1) {
- if (!removal)
+
+ private MultUpdateNode getMultUpdateNode(boolean negate, Descriptor d, RepairGenerator rg) {
+ Termination termination=rg.termination;
+ MultUpdateNode mun=null;
+ GraphNode gn;
+ if (negate)
+ gn=(GraphNode)termination.abstractremove.get(d);
+ else
+ gn=(GraphNode)termination.abstractadd.get(d);
+ TermNode tn=(TermNode)gn.getOwner();
+ for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
+ GraphNode gn2=((GraphNode.Edge) edgeit.next()).getTarget();
+ if (!rg.removed.contains(gn2)) {
+ TermNode tn2=(TermNode)gn2.getOwner();
+ if (tn2.getType()==TermNode.UPDATE) {
+ mun=tn2.getUpdate();
+ break;
+ }
+ }
+ }
+ if (mun==null)
+ throw new Error("Can't find update node!");
+ return mun;
+ }
+
+ public void generate_abstract(CodeWriter cr, Updates u, RepairGenerator rg) {
+ State state=rg.state;
+ Expr abstractexpr=u.getLeftExpr();
+ boolean negated=u.negate;
+ Descriptor d=null;
+ Expr left=null;
+ Expr right=null;
+ boolean istuple=false;
+ if (abstractexpr instanceof TupleOfExpr) {
+ TupleOfExpr toe=(TupleOfExpr) abstractexpr;
+ d=toe.relation;
+ left=toe.left;
+ right=toe.right;
+ istuple=true;
+ } else if (abstractexpr instanceof ElementOfExpr) {
+ ElementOfExpr eoe=(ElementOfExpr) abstractexpr;
+ d=eoe.set;
+ left=eoe.element;
+ istuple=false;
+ } else {
+ throw new Error("Unsupported Expr");
+ }
+ MultUpdateNode mun=getMultUpdateNode(negated,d,rg);
+ VarDescriptor leftvar=VarDescriptor.makeNew("leftvar");
+ VarDescriptor rightvar=VarDescriptor.makeNew("rightvar");
+ left.generate(cr, leftvar);
+ if (istuple)
+ right.generate(cr,rightvar);
+
+ if (negated) {
+ if (istuple) {
+ RelationDescriptor rd=(RelationDescriptor)d;
+ boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+ boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+ if (usageimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+ if (usageinvimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->remove((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ for(int i=0;i<state.vRules.size();i++) {
+ Rule r=(Rule)state.vRules.get(i);
+ if (r.getInclusion().getTargetDescriptors().contains(rd)) {
+ for(int j=0;j<mun.numUpdates();j++) {
+ UpdateNode un=mun.getUpdate(i);
+ if (un.getRule()==r) {
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(rg.strepairtable+"->addrelation("+rd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
+ }
+ }
+ }
+ }
+ } else {
+ SetDescriptor sd=(SetDescriptor) d;
+ cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ for(int i=0;i<state.vRules.size();i++) {
+ Rule r=(Rule)state.vRules.get(i);
+ if (r.getInclusion().getTargetDescriptors().contains(sd)) {
+ for(int j=0;j<mun.numUpdates();j++) {
+ UpdateNode un=mun.getUpdate(j);
+ if (un.getRule()==r) {
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(rg.strepairtable+"->addset("+sd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* Generate update */
+ if (istuple) {
+ RelationDescriptor rd=(RelationDescriptor) d;
+ boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+ boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+ if (usageimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+ if (usageinvimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->add((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ UpdateNode un=mun.getUpdate(0);
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
+ } else {
+ SetDescriptor sd=(SetDescriptor)d;
+ cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ UpdateNode un=mun.getUpdate(0);
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+");");
+ }
+ }
+
+ }
+
+ public void generate(CodeWriter cr, boolean removal, boolean modify, String slot0, String slot1, String slot2, RepairGenerator rg) {
+ if (!removal&&!modify)
generate_bindings(cr, slot0,slot1);
for(int i=0;i<updates.size();i++) {
Updates u=(Updates)updates.get(i);
VarDescriptor right=VarDescriptor.makeNew("right");
- if (u.getType()==Updates.ABSTRACT)
- throw new Error("Abstract update not implemented");
+ if (u.getType()==Updates.ABSTRACT) {
+ generate_abstract(cr, u, rg);
+ return;
+ }
switch(u.getType()) {
case Updates.EXPR:
u.getRightExpr().generate(cr,right);
break;
case Updates.POSITION:
+ case Updates.ACCESSPATH:
if (u.getRightPos()==0)
cr.outputline("int "+right.getSafeSymbol()+"="+slot0+";");
else if (u.getRightPos()==1)
cr.outputline("int "+right.getSafeSymbol()+"="+slot1+";");
+ else if (u.getRightPos()==2)
+ cr.outputline("int "+right.getSafeSymbol()+"="+slot2+";");
else throw new Error("Error w/ Position");
break;
default:
throw new Error();
}
+
+ if (u.getType()==Updates.ACCESSPATH) {
+ VarDescriptor newright=VarDescriptor.makeNew("right");
+ /* Need to do the modulo computation here...FIXME */
+ right=newright;
+ }
VarDescriptor left=VarDescriptor.makeNew("left");
u.getLeftExpr().generate(cr,left);
Opcode op=u.getOpcode();
- cr.outputline("if ("+left.getSafeSymbol()+op+right.getSafeSymbol()+")");
+ cr.outputline("if (!("+left.getSafeSymbol()+op+right.getSafeSymbol()+"))");
cr.startblock();
if (op==Opcode.GT)
cr.outputline(vd.getSafeSymbol()+"="+right.getSafeSymbol()+";");
} else if (u.isField()) {
/* NEED TO FIX */
+ Expr subexpr=((DotExpr)u.getLeftExpr()).getExpr();
+ Expr intindex=((DotExpr)u.getLeftExpr()).getIndex();
+ VarDescriptor subvd=VarDescriptor.makeNew("subexpr");
+ VarDescriptor indexvd=VarDescriptor.makeNew("index");
+ subexpr.generate(cr,subvd);
+ if (intindex!=null)
+ intindex.generate(cr,indexvd);
+ FieldDescriptor fd=(FieldDescriptor)u.getDescriptor();
+ StructureTypeDescriptor std=(StructureTypeDescriptor)subexpr.getType();
+ if (fd instanceof ArrayDescriptor) {
+ fd = ((ArrayDescriptor) fd).getField();
+ }
+
+ Expr offsetbits = std.getOffsetExpr(fd);
+ if (intindex != null) {
+ Expr basesize = fd.getBaseSizeExpr();
+ offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
+ }
+ Expr offsetbytes = new OpExpr(Opcode.SHR, offsetbits,new IntegerLiteralExpr(3));
+ Expr byteaddress=new OpExpr(Opcode.ADD, offsetbytes, subexpr);
+ VarDescriptor addr=VarDescriptor.makeNew("byteaddress");
+ byteaddress.generate(cr,addr);
+
+ if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
+ ReservedTypeDescriptor rtd=(ReservedTypeDescriptor)fd.getType();
+ if (rtd==ReservedTypeDescriptor.INT) {
+ cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.SHORT) {
+ cr.outputline("*((short *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.BYTE) {
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.BIT) {
+ Expr tmp = new OpExpr(Opcode.SHL, offsetbytes, new IntegerLiteralExpr(3));
+ Expr offset=new OpExpr(Opcode.SUB, offsetbits, tmp);
+ Expr mask=new OpExpr(Opcode.SHR, new IntegerLiteralExpr(1), offset);
+ VarDescriptor maskvar=VarDescriptor.makeNew("mask");
+ mask.generate(cr,maskvar);
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")|="+maskvar.getSafeSymbol()+";");
+ cr.outputline("if (!"+right.getSafeSymbol()+")");
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")^="+maskvar.getSafeSymbol()+";");
+ } else throw new Error();
+ } else {
+ /* Pointer */
+ cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ }
}
cr.endblock();
-
}
}
+
private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
for(int i=0;i<bindings.size();i++) {
Binding b=(Binding)bindings.get(i);
- if (b.search)
- throw new Error("Search not implemented for bindings");
- VarDescriptor vd=b.getVar();
- switch(b.getPosition()) {
- case 0:
- cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot0+";");
- break;
- case 1:
- cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot1+";");
- break;
- default:
- throw new Error("Slot >1 doesn't exist.");
+
+ if (b.getType()==Binding.SEARCH) {
+ VarDescriptor vd=b.getVar();
+ cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+b.getSet().getSafeSymbol()+"->firstkey();");
+ } else if (b.getType()==Binding.CREATE) {
+ throw new Error("Creation not supported");
+ // source.generateSourceAlloc(cr,vd,b.getSet());
+ } else {
+ VarDescriptor vd=b.getVar();
+ switch(b.getPosition()) {
+ case 0:
+ cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot0+";");
+ break;
+ case 1:
+ cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot1+";");
+ break;
+ default:
+ throw new Error("Slot >1 doesn't exist.");
+ }
}
}
}