+ return new NodePair(cond.getBegin(), sbody.getEnd());
+ }
+
+ private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp, FlatNode endnode) {
+ FlatNode begin=null;
+ FlatNode end=endnode;
+ NodePair prev_true_branch = null;
+ NodePair prev_false_branch = null;
+ for(int i=0; i<bn.size(); i++) {
+ SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
+ HashSet oldbs=breakset;
+ breakset=new HashSet();
+
+ NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
+ Vector<SwitchLabelNode> 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);
+ fon.setNumLine(sln.getNumLine());
+ left.getEnd().addNext(fon);
+
+ FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
+ fcb.setNumLine(bn.getNumLine());
+ 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.setNumLine(ln.getNumLine());
+ 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.setNumLine(ln.getNumLine());
+ 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.setNumLine(ln.getNumLine());
+ 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.setNumLine(rntree.getNumLine());
+ rnflat.addNext(fe);
+ FlatNode ln=rnflat;
+ if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
+ FlatNode end = null;
+ MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+ for(int j = this.lockStack.size(); j > 0; j--) {
+ TempDescriptor thistd = this.lockStack.elementAt(j-1);
+ FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
+ fcunlock.setNumLine(rntree.getNumLine());
+ if(end != null) {
+ end.addNext(fcunlock);
+ }
+ end = fcunlock;
+ }
+ end.addNext(ln);
+ ln=end;
+ }
+ 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.setNumLine(ten.getNumLine());
+ 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<ccs.size(); i++) {
+ ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
+ /* Flatten the arguments */
+ TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
+ String[] vars=new String[cc.numArgs()];
+ for(int j=0; j<cc.numArgs(); j++) {
+ ExpressionNode en=cc.getArg(j);
+ TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
+ temps[j]=td;
+ vars[j]=cc.getVar(j);
+ NodePair np=flattenExpressionNode(en, td);
+ last.addNext(np.getBegin());
+ last=np.getEnd();
+ }
+
+ FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
+ last.addNext(fcn);
+ last=fcn;
+ }
+ return new NodePair(begin,last);
+ }
+
+ private NodePair flattenSubBlockNode(SubBlockNode sbn) {
+ return flattenBlockNode(sbn.getBlockNode());
+ }
+
+ private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
+ TempDescriptor montmp=null;
+ FlatNode first = null;
+ FlatNode end = null;
+ if(sbn.getExpr() instanceof ClassTypeNode) {
+ montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
+ } else {
+ montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
+ NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
+ first = npexp.getBegin();
+ end = npexp.getEnd();
+ }
+ this.lockStack.push(montmp);
+ NodePair npblock=flattenBlockNode(sbn.getBlockNode());
+
+ MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
+ FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
+ fcen.setNumLine(sbn.getNumLine());
+
+ MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+ FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
+ fcex.setNumLine(sbn.getNumLine());
+
+ this.lockStack.pop();
+
+ if(first != null) {
+ end.addNext(fcen);
+ } else {
+ first = fcen;
+ }
+ fcen.addNext(npblock.getBegin());
+
+ if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
+ npblock.getEnd().addNext(fcex);
+ }
+
+ /*if(npblock.getEnd() != null) {
+ npblock.getEnd().addNext(fcex);
+ }*/
+ return new NodePair(first, fcex);
+ }
+
+ private NodePair flattenAtomicNode(AtomicNode sbn) {
+ NodePair np=flattenBlockNode(sbn.getBlockNode());
+ FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
+ faen.setNumLine(sbn.getNumLine());
+ FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
+ faen.addNext(np.getBegin());
+ np.getEnd().addNext(faexn);
+ return new NodePair(faen, faexn);
+ }
+
+ private NodePair flattenGenReachNode( GenReachNode grn ) {
+ FlatGenReachNode fgrn = new FlatGenReachNode( grn.getGraphName() );
+ return new NodePair( fgrn, fgrn );
+ }
+
+ private NodePair flattenSESENode(SESENode sn) {
+ if( sn.isStart() ) {
+ FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
+ fsen.setNumLine(sn.getNumLine());
+ sn.setFlatEnter(fsen);
+ return new NodePair(fsen, fsen);
+ }
+
+ FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
+ sn.setFlatExit(fsexn);
+ FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
+ fsexn.setFlatEnter(fsen);
+ sn.getStart().getFlatEnter().setFlatExit( fsexn );
+
+ return new NodePair(fsexn, fsexn);
+ }
+
+ private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
+ FlatNop fn=new FlatNop();
+ if (cbn.isBreak())
+ breakset.add(fn);
+ else
+ continueset.add(fn);
+ return new NodePair(fn,null);
+ }
+
+ private NodePair flattenInstanceOfNode(InstanceOfNode tn, TempDescriptor out_temp) {
+ TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
+ NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
+ FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
+ fion.setNumLine(tn.getNumLine());
+ cond.getEnd().addNext(fion);
+ return new NodePair(cond.getBegin(),fion);
+ }
+
+ private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
+ boolean isGlobal = false;
+ String disjointId = null;
+ // get the type the array to be initialized
+ TypeDescriptor td = ain.getType();
+
+ // create a new array of size equal to the array initializer
+ FlatNode first=null;
+ FlatNode last=null;
+ TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
+ FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
+ fln_tmp.setNumLine(ain.getNumLine());
+ first = last=fln_tmp;
+
+ // create the new array
+ FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
+ last.addNext(fn);
+ last = fn;
+
+ // initialize the new array
+ for(int i = 0; i < ain.numVarInitializers(); i++) {
+ ExpressionNode var_init_node = ain.getVarInitializer(i);
+ TempDescriptor tmp_toinit = out_temp;
+ TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
+ // index=i
+ TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
+ FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
+ fln.setNumLine(ain.getNumLine());
+ // calculate the initial value
+ NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
+ // TODO wrapper class process is missing now
+ /*if(td.isArray() && td.dereference().iswrapper()) {
+ }*/
+ FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
+ fsen.setNumLine(ain.getNumLine());
+ last.addNext(fln);
+ fln.addNext(np_init.getBegin());
+ np_init.getEnd().addNext(fsen);
+ last = fsen;
+ }
+
+ return new NodePair(first, last);
+ }
+
+ private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
+ TempDescriptor cond_temp=TempDescriptor.tempFactory("tert_cond",new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ TempDescriptor true_temp=TempDescriptor.tempFactory("tert_true",tn.getTrueExpr().getType());
+ TempDescriptor fals_temp=TempDescriptor.tempFactory("tert_fals",tn.getFalseExpr().getType());
+
+ NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
+ FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+ fcb.setNumLine(tn.getNumLine());
+
+ NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
+ FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
+ fonT.setNumLine(tn.getNumLine());
+
+ NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
+ FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
+ fonF.setNumLine(tn.getNumLine());
+
+ FlatNop nopend=new FlatNop();
+
+ cond.getEnd().addNext(fcb);
+
+ fcb.addTrueNext(trueExpr.getBegin());
+ fcb.addFalseNext(falseExpr.getBegin());
+
+ trueExpr.getEnd().addNext(fonT);
+ fonT.addNext(nopend);
+
+ falseExpr.getEnd().addNext(fonF);
+ fonF.addNext(nopend);
+
+ return new NodePair(cond.getBegin(), nopend);
+ }
+
+ private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
+ switch(bsn.kind()) {
+ case Kind.BlockExpressionNode:
+ return flattenBlockExpressionNode((BlockExpressionNode)bsn);
+
+ case Kind.DeclarationNode:
+ return flattenDeclarationNode((DeclarationNode)bsn);
+
+ case Kind.TagDeclarationNode:
+ return flattenTagDeclarationNode((TagDeclarationNode)bsn);
+
+ case Kind.IfStatementNode:
+ return flattenIfStatementNode((IfStatementNode)bsn);
+
+ case Kind.SwitchStatementNode:
+ return flattenSwitchStatementNode((SwitchStatementNode)bsn);
+
+ case Kind.LoopNode:
+ return flattenLoopNode((LoopNode)bsn);
+
+ case Kind.ReturnNode:
+ return flattenReturnNode((IR.Tree.ReturnNode)bsn);
+
+ case Kind.TaskExitNode:
+ return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
+
+ case Kind.SubBlockNode:
+ return flattenSubBlockNode((SubBlockNode)bsn);
+
+ case Kind.AtomicNode:
+ return flattenAtomicNode((AtomicNode)bsn);
+
+ case Kind.SynchronizedNode:
+ return flattenSynchronizedNode((SynchronizedNode)bsn);
+
+ case Kind.SESENode:
+ return flattenSESENode((SESENode)bsn);
+
+ case Kind.GenReachNode:
+ return flattenGenReachNode((GenReachNode)bsn);
+
+ case Kind.ContinueBreakNode:
+ return flattenContinueBreakNode((ContinueBreakNode)bsn);