package IR.Flat;
import IR.*;
import IR.Tree.*;
import java.util.*;
public class BuildFlat {
State state;
Hashtable temptovar;
MethodDescriptor currmd;
TypeUtil typeutil;
HashSet breakset;
HashSet continueset;
FlatExit fe;
public BuildFlat(State st, TypeUtil typeutil) {
state=st;
temptovar=new Hashtable();
this.typeutil=typeutil;
this.breakset=new HashSet();
this.continueset=new HashSet();
}
public Hashtable getMap() {
return temptovar;
}
public void buildFlat() {
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
ClassDescriptor cn=(ClassDescriptor)it.next();
flattenClass(cn);
}
Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();
while(task_it.hasNext()) {
TaskDescriptor td=(TaskDescriptor)task_it.next();
flattenTask(td);
}
}
private void flattenTask(TaskDescriptor td) {
BlockNode bn=state.getMethodBody(td);
NodePair np=flattenBlockNode(bn);
FlatNode fn=np.getBegin();
fe=new FlatExit();
FlatNode fn2=np.getEnd();
if (fn2!=null&& fn2.kind()!=FKind.FlatReturnNode) {
FlatReturnNode rnflat=new FlatReturnNode(null);
rnflat.addNext(fe);
fn2.addNext(rnflat);
}
FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE);
ffan.addNext(fn);
FlatMethod fm=new FlatMethod(td, fe);
fm.addNext(ffan);
Hashtable visitedset=new Hashtable();
for(int i=0; i
inside flattenBlockExpressionNode\n");
TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
return flattenExpressionNode(en.getExpression(),tmp);
}
private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
np.getEnd().addNext(fcn);
return new NodePair(np.getBegin(),fcn);
}
private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
return new NodePair(fln,fln);
}
private NodePair flattenOffsetNode(OffsetNode ofn, TempDescriptor out_temp) {
FlatOffsetNode fln = new FlatOffsetNode(ofn.getClassType(), ofn.getField(), out_temp);
return new NodePair(fln, fln);
}
private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
TypeDescriptor td=con.getType();
if (!td.isArray()) {
FlatNode fn=new FlatNew(td, out_temp, con.isGlobal(), con.getDisjointId());
FlatNode last=fn;
//handle wrapper fields
ClassDescriptor cd=td.getClassDesc();
for(Iterator fieldit=cd.getFields();fieldit.hasNext();) {
FieldDescriptor fd=(FieldDescriptor)fieldit.next();
if (fd.getType().iswrapper()) {
TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType());
FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal());
FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp);
last.addNext(fnwrapper);
fnwrapper.addNext(fsfn);
last=fsfn;
}
}
TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
// Build arguments
for(int i=0; i1) {
NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
fn.addNext(np.getBegin());
return new NodePair(first,np.getEnd());
} else if (td.isArray()&&td.dereference().iswrapper()) {
NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
fn.addNext(np.getBegin());
return new NodePair(first,np.getEnd());
} else
return new NodePair(first, fn);
} else if(state.MGC) {
// array creation with initializers
return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
}
return null;
}
}
private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
FlatNop fnop=new FlatNop(); //last node
//index=0
FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
//tmpone=1
FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
FlatCondBranch fcb=new FlatCondBranch(tmpbool);
fcb.setTrueProb(State.TRUEPROB);
fcb.setLoop();
//is index slnv = sbn.getSwitchConditions();
FlatNode cond_begin = null;
NodePair prev_fnp = null;
for(int j = 0; j < slnv.size(); j++) {
SwitchLabelNode sln = slnv.elementAt(j);
NodePair left = null;
NodePair false_np = null;
if(sln.isDefault()) {
left = body;
} else {
TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
Operation op=new Operation(Operation.EQUAL);
left=flattenExpressionNode(sln.getCondition(), temp_left);
FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
left.getEnd().addNext(fon);
FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
fcb.setTrueProb(State.TRUEPROB);
FlatNop nop=new FlatNop();
false_np=new NodePair(nop,nop);
fon.addNext(fcb);
fcb.addTrueNext(body.getBegin());
fcb.addFalseNext(false_np.getBegin());
}
if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
prev_fnp.getEnd().addNext(left.getBegin());
}
prev_fnp = false_np;
if (begin==null) {
begin = left.getBegin();
}
if(cond_begin == null) {
cond_begin = left.getBegin();
}
}
if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
prev_false_branch.getEnd().addNext(cond_begin);
}
prev_false_branch = prev_fnp;
if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
prev_true_branch.getEnd().addNext(body.getBegin());
}
prev_true_branch = body;
for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
FlatNode fn=(FlatNode)breakit.next();
breakit.remove();
fn.addNext(endnode);
}
breakset=oldbs;
}
if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
prev_true_branch.getEnd().addNext(endnode);
}
if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
prev_false_branch.getEnd().addNext(endnode);
}
if(begin == null) {
end=begin=new FlatNop();
}
return new NodePair(begin,end);
}
private NodePair flattenLoopNode(LoopNode ln) {
HashSet oldbs=breakset;
HashSet oldcs=continueset;
breakset=new HashSet();
continueset=new HashSet();
if (ln.getType()==LoopNode.FORLOOP) {
NodePair initializer=flattenBlockNode(ln.getInitializer());
TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
NodePair update=flattenBlockNode(ln.getUpdate());
NodePair body=flattenBlockNode(ln.getBody());
FlatNode begin=initializer.getBegin();
FlatCondBranch fcb=new FlatCondBranch(cond_temp);
fcb.setTrueProb(State.TRUEPROB);
fcb.setLoop();
FlatNop nopend=new FlatNop();
FlatBackEdge backedge=new FlatBackEdge();
FlatNop nop2=new FlatNop();
initializer.getEnd().addNext(nop2);
nop2.addNext(condition.getBegin());
if (body.getEnd()!=null)
body.getEnd().addNext(update.getBegin());
update.getEnd().addNext(backedge);
backedge.addNext(condition.getBegin());
condition.getEnd().addNext(fcb);
fcb.addFalseNext(nopend);
fcb.addTrueNext(body.getBegin());
for(Iterator contit=continueset.iterator();contit.hasNext();) {
FlatNode fn=(FlatNode)contit.next();
contit.remove();
fn.addNext(update.getBegin());
}
for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
FlatNode fn=(FlatNode)breakit.next();
breakit.remove();
fn.addNext(nopend);
}
breakset=oldbs;
continueset=oldcs;
return new NodePair(begin,nopend);
} else if (ln.getType()==LoopNode.WHILELOOP) {
TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
NodePair body=flattenBlockNode(ln.getBody());
FlatNode begin=condition.getBegin();
FlatCondBranch fcb=new FlatCondBranch(cond_temp);
fcb.setTrueProb(State.TRUEPROB);
fcb.setLoop();
FlatNop nopend=new FlatNop();
FlatBackEdge backedge=new FlatBackEdge();
if (body.getEnd()!=null)
body.getEnd().addNext(backedge);
backedge.addNext(condition.getBegin());
condition.getEnd().addNext(fcb);
fcb.addFalseNext(nopend);
fcb.addTrueNext(body.getBegin());
for(Iterator contit=continueset.iterator();contit.hasNext();) {
FlatNode fn=(FlatNode)contit.next();
contit.remove();
fn.addNext(backedge);
}
for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
FlatNode fn=(FlatNode)breakit.next();
breakit.remove();
fn.addNext(nopend);
}
breakset=oldbs;
continueset=oldcs;
return new NodePair(begin,nopend);
} else if (ln.getType()==LoopNode.DOWHILELOOP) {
TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
NodePair body=flattenBlockNode(ln.getBody());
FlatNode begin=body.getBegin();
FlatCondBranch fcb=new FlatCondBranch(cond_temp);
fcb.setTrueProb(State.TRUEPROB);
fcb.setLoop();
FlatNop nopend=new FlatNop();
FlatBackEdge backedge=new FlatBackEdge();
if (body.getEnd()!=null)
body.getEnd().addNext(condition.getBegin());
condition.getEnd().addNext(fcb);
fcb.addFalseNext(nopend);
fcb.addTrueNext(backedge);
backedge.addNext(body.getBegin());
for(Iterator contit=continueset.iterator();contit.hasNext();) {
FlatNode fn=(FlatNode)contit.next();
contit.remove();
fn.addNext(condition.getBegin());
}
for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
FlatNode fn=(FlatNode)breakit.next();
breakit.remove();
fn.addNext(nopend);
}
breakset=oldbs;
continueset=oldcs;
return new NodePair(begin,nopend);
} else throw new Error();
}
private NodePair flattenReturnNode(ReturnNode rntree) {
TempDescriptor retval=null;
NodePair cond=null;
if (rntree.getReturnExpression()!=null) {
retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
}
FlatReturnNode rnflat=new FlatReturnNode(retval);
rnflat.addNext(fe);
FlatNode ln=rnflat;
if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
TempDescriptor thistd=null;
if(currmd.getModifiers().isStatic()) {
// need to lock the Class object
thistd=new TempDescriptor("classobj", currmd.getClassDesc());
} else {
// lock this object
thistd=getTempforVar(currmd.getThis());
}
FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
fc.addNext(ln);
ln=fc;
}
if (state.DSM&&currmd.getModifiers().isAtomic()) {
FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
faen.addNext(ln);
ln=faen;
}
if (cond!=null) {
cond.getEnd().addNext(ln);
return new NodePair(cond.getBegin(),null);
} else
return new NodePair(ln,null);
}
private NodePair flattenTaskExitNode(TaskExitNode ten) {
FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
ffan.setTaskExitIndex(ten.getTaskExitIndex());
updateFlagActionNode(ffan, ten.getFlagEffects());
NodePair fcn=flattenConstraintCheck(ten.getChecks());
ffan.addNext(fcn.getBegin());
FlatReturnNode rnflat=new FlatReturnNode(null);
rnflat.addNext(fe);
fcn.getEnd().addNext(rnflat);
return new NodePair(ffan, null);
}
private NodePair flattenConstraintCheck(Vector ccs) {
FlatNode begin=new FlatNop();
if (ccs==null)
return new NodePair(begin,begin);
FlatNode last=begin;
for(int i=0; i