6 public class BuildFlat {
9 MethodDescriptor currmd;
12 public BuildFlat(State st, TypeUtil typeutil) {
14 temptovar=new Hashtable();
15 this.typeutil=typeutil;
18 public Hashtable getMap() {
22 public void buildFlat() {
23 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
25 ClassDescriptor cn=(ClassDescriptor)it.next();
29 Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();
30 while(task_it.hasNext()) {
31 TaskDescriptor td=(TaskDescriptor)task_it.next();
36 private void flattenTask(TaskDescriptor td) {
37 BlockNode bn=state.getMethodBody(td);
38 NodePair np=flattenBlockNode(bn);
39 FlatNode fn=np.getBegin();
40 if (np.getEnd().kind()!=FKind.FlatReturnNode) {
41 FlatReturnNode rnflat=new FlatReturnNode(null);
42 np.getEnd().addNext(rnflat);
45 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE);
48 FlatMethod fm=new FlatMethod(td);
51 Hashtable visitedset=new Hashtable();
53 for(int i=0;i<td.numParameters();i++) {
54 VarDescriptor paramvd=td.getParameter(i);
55 fm.addParameterTemp(getTempforVar(paramvd));
56 TagExpressionList tel=td.getTag(paramvd);
57 //BUG added next line to fix...to test feed in any task program
59 for(int j=0;j<tel.numTags();j++) {
60 TagVarDescriptor tvd=(TagVarDescriptor) td.getParameterTable().getFromSameScope(tel.getName(j));
61 TempDescriptor tagtmp=getTempforVar(tvd);
62 if (!visitedset.containsKey(tvd.getName())) {
63 visitedset.put(tvd.getName(),tvd.getTag());
64 fm.addTagTemp(tagtmp);
66 TagDescriptor tmptd=(TagDescriptor) visitedset.get(tvd.getName());
67 if (!tmptd.equals(tvd.getTag()))
68 throw new Error("Two different tag types with same name as parameters to:"+td);
70 tel.setTemp(j, tagtmp);
74 /* Flatten Vector of Flag Effects */
75 Vector flags=td.getFlagEffects();
76 updateFlagActionNode(ffan,flags);
78 state.addFlatCode(td,fm);
82 /* This method transforms a vector of FlagEffects into the FlatFlagActionNode */
83 private void updateFlagActionNode(FlatFlagActionNode ffan, Vector flags) {
84 if (flags==null) // Do nothing if the flag effects vector is empty
87 for(int i=0;i<flags.size();i++) {
88 FlagEffects fes=(FlagEffects)flags.get(i);
89 TempDescriptor flagtemp=getTempforVar(fes.getVar());
91 for(int j=0;j<fes.numEffects();j++) {
92 FlagEffect fe=fes.getEffect(j);
93 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
96 for(int j=0;j<fes.numTagEffects();j++) {
97 TagEffect te=fes.getTagEffect(j);
98 TempDescriptor tagtemp=getTempforVar(te.getTag());
100 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
105 private void flattenClass(ClassDescriptor cn) {
106 Iterator methodit=cn.getMethods();
107 while(methodit.hasNext()) {
108 currmd=(MethodDescriptor)methodit.next();
109 BlockNode bn=state.getMethodBody(currmd);
110 NodePair np=flattenBlockNode(bn);
111 FlatNode fn=np.getBegin();
112 if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
113 MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
114 TempDescriptor thistd=getTempforVar(currmd.getThis());
115 FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
118 if (np.getEnd().kind()!=FKind.FlatReturnNode) {
119 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
120 FlatCall fcunlock=new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
121 np.getEnd().addNext(fcunlock);
122 FlatReturnNode rnflat=new FlatReturnNode(null);
123 fcunlock.addNext(rnflat);
125 } else if (state.DSM&&currmd.getModifiers().isAtomic()) {
126 FlatAtomicEnterNode an=new FlatAtomicEnterNode();
129 if (np.getEnd().kind()!=FKind.FlatReturnNode) {
130 FlatAtomicExitNode aen=new FlatAtomicExitNode();
131 np.getEnd().addNext(aen);
132 FlatReturnNode rnflat=new FlatReturnNode(null);
135 } else if (np.getEnd().kind()!=FKind.FlatReturnNode) {
136 FlatReturnNode rnflat=new FlatReturnNode(null);
137 np.getEnd().addNext(rnflat);
140 FlatMethod fm=new FlatMethod(currmd);
142 if (!currmd.isStatic())
143 fm.addParameterTemp(getTempforParam(currmd.getThis()));
144 for(int i=0;i<currmd.numParameters();i++) {
145 fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
147 state.addFlatCode(currmd,fm);
151 private NodePair flattenBlockNode(BlockNode bn) {
154 for(int i=0;i<bn.size();i++) {
155 NodePair np=flattenBlockStatementNode(bn.get(i));
156 FlatNode np_begin=np.getBegin();
157 FlatNode np_end=np.getEnd();
164 end.addNext(np_begin);
169 end=begin=new FlatNop();
171 return new NodePair(begin,end);
174 private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
175 TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
176 return flattenExpressionNode(en.getExpression(),tmp);
179 private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
180 TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
181 NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
182 FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
183 np.getEnd().addNext(fcn);
184 return new NodePair(np.getBegin(),fcn);
187 private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
188 FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
189 return new NodePair(fln,fln);
192 private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
193 TypeDescriptor td=con.getType();
195 FlatNew fn=new FlatNew(td, out_temp, con.isGlobal());
196 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
198 if (td.getClassDesc().hasFlags()) {
199 // if (con.getFlagEffects()!=null) {
200 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
201 FlagEffects fes=con.getFlagEffects();
202 TempDescriptor flagtemp=out_temp;
204 for(int j=0;j<fes.numEffects();j++) {
205 FlagEffect fe=fes.getEffect(j);
206 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
208 for(int j=0;j<fes.numTagEffects();j++) {
209 TagEffect te=fes.getTagEffect(j);
210 TempDescriptor tagtemp=getTempforVar(te.getTag());
212 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
215 ffan.addFlagAction(flagtemp, null, false);
221 for(int i=0;i<con.numArgs();i++) {
222 ExpressionNode en=con.getArg(i);
223 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
225 NodePair np=flattenExpressionNode(en, tmp);
226 last.addNext(np.getBegin());
229 MethodDescriptor md=con.getConstructor();
230 //Call to constructor
231 FlatCall fc=new FlatCall(md, null, out_temp, temps);
234 return new NodePair(fn,last);
238 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
239 for (int i=0;i<con.numArgs();i++) {
240 ExpressionNode en=con.getArg(i);
241 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
243 NodePair np=flattenExpressionNode(en, tmp);
247 last.addNext(np.getBegin());
250 TempDescriptor tmp2=(i==0)?
252 TempDescriptor.tempFactory("arg",en.getType());
254 FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal());
256 if (temps.length>1) {
257 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
258 fn.addNext(np.getBegin());
259 return new NodePair(first,np.getEnd());
261 return new NodePair(first, fn);
265 private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
266 TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
267 TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
268 FlatNop fnop=new FlatNop();//last node
271 FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
273 FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
275 TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
277 FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
278 FlatCondBranch fcb=new FlatCondBranch(tmpbool);
280 TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
281 FlatNew fn=new FlatNew(td, new_tmp, temparray[i+1], isglobal);
282 FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
284 FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
290 fcb.addFalseNext(fnop);
292 //Recursive call here
293 if ((i+2)<temparray.length) {
294 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
295 fsen.addNext(np2.getBegin());
296 np2.getEnd().addNext(fon);
301 return new NodePair(fln, fnop);
304 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
305 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
308 TempDescriptor thisarg=null;
310 if (min.getExpression()!=null) {
311 thisarg=TempDescriptor.tempFactory("thisarg",min.getExpression().getType());
312 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
318 for(int i=0;i<min.numArgs();i++) {
319 ExpressionNode en=min.getArg(i);
320 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
322 NodePair np=flattenExpressionNode(en, td);
326 last.addNext(np.getBegin());
330 MethodDescriptor md=min.getMethod();
332 //Call to constructor
335 if(md.getReturnType()==null||md.getReturnType().isVoid())
336 fc=new FlatCall(md, null, thisarg, temps);
338 fc=new FlatCall(md, out_temp, thisarg, temps);
343 return new NodePair(first,fc);
346 private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
347 TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
348 NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
349 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
350 npe.getEnd().addNext(fn);
351 return new NodePair(npe.getBegin(),fn);
354 private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
355 TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
356 TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
357 NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
358 NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
359 FlatElementNode fn=new FlatElementNode(tmp,tmpindex,out_temp);
360 npe.getEnd().addNext(npi.getBegin());
361 npi.getEnd().addNext(fn);
362 return new NodePair(npe.getBegin(),fn);
365 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
367 // left side is variable
368 // left side is field
369 // left side is array
371 Operation base=an.getOperation().getBaseOp();
372 boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC);
375 //rewrite the base operation
376 base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB);
380 TempDescriptor src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType());
383 if (an.getSrc()!=null) {
384 NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
385 first=np_src.getBegin();
386 last=np_src.getEnd();
388 FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT) ,new Integer(1),src_tmp);
393 if (an.getDest().kind()==Kind.FieldAccessNode) {
394 //We are assigning an object field
396 FieldAccessNode fan=(FieldAccessNode)an.getDest();
397 ExpressionNode en=fan.getExpression();
398 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
399 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
401 first=np_baseexp.getBegin();
403 last.addNext(np_baseexp.getBegin());
404 last=np_baseexp.getEnd();
406 //See if we need to perform an operation
408 //If it is a preinc we need to store the initial value
409 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
410 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
412 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
415 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
421 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
425 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
429 return new NodePair(first, last);
430 } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
431 //We are assigning an array element
434 ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
435 ExpressionNode en=aan.getExpression();
436 ExpressionNode enindex=aan.getIndex();
437 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
438 TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
439 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
440 NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
442 first=np_baseexp.getBegin();
444 last.addNext(np_baseexp.getBegin());
445 np_baseexp.getEnd().addNext(np_indexexp.getBegin());
446 last=np_indexexp.getEnd();
448 //See if we need to perform an operation
450 //If it is a preinc we need to store the initial value
451 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
452 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
454 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
457 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
464 FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
468 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
472 return new NodePair(first, last);
473 } else if (an.getDest().kind()==Kind.NameNode) {
474 //We could be assigning a field or variable
475 NameNode nn=(NameNode)an.getDest();
476 if (nn.getExpression()!=null) {
478 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
479 ExpressionNode en=fan.getExpression();
480 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
481 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
483 first=np_baseexp.getBegin();
485 last.addNext(np_baseexp.getBegin());
486 last=np_baseexp.getEnd();
488 //See if we need to perform an operation
490 //If it is a preinc we need to store the initial value
491 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
492 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
494 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
497 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
504 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
508 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
512 return new NodePair(first, last);
514 if (nn.getField()!=null) {
518 //See if we need to perform an operation
520 //If it is a preinc we need to store the initial value
521 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
522 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
524 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), getTempforVar(nn.getVar()), src_tmp2);
531 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
537 FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
545 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
549 return new NodePair(first, last);
552 //See if we need to perform an operation
555 //If it is a preinc we need to store the initial value
556 TempDescriptor src_tmp2=getTempforVar(nn.getVar());
557 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType());
559 FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
567 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
576 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
580 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
584 return new NodePair(first, last);
591 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
592 if (nn.getExpression()!=null) {
593 /* Hack - use subtree instead */
594 return flattenExpressionNode(nn.getExpression(),out_temp);
595 } else if (nn.getField()!=null) {
596 TempDescriptor tmp=getTempforVar(nn.getVar());
597 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
598 return new NodePair(ffn,ffn);
600 TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
603 out_temp.setTag(tmp.getTag());
605 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
606 return new NodePair(fon,fon);
610 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
611 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
612 TempDescriptor temp_right=null;
614 Operation op=on.getOp();
615 /* We've moved this to assignment nodes
617 if (op.getOp()==Operation.POSTINC||
618 op.getOp()==Operation.POSTDEC||
619 op.getOp()==Operation.PREINC||
620 op.getOp()==Operation.PREDEC) {
621 LiteralNode ln=new LiteralNode("int",new Integer(1));
622 ln.setType(new TypeDescriptor(TypeDescriptor.INT));
624 AssignmentNode an=new AssignmentNode(on.getLeft(),
625 new OpNode(on.getLeft(),ln,
626 new Operation((op.getOp()==Operation.POSTINC||op.getOp()==Operation.PREINC)?Operation.PLUS:Operation.MINUS))
628 if (op.getOp()==Operation.POSTINC||
629 op.getOp()==Operation.POSTDEC) {
630 //Can't do, this could have side effects
631 NodePair left=flattenExpressionNode(on.getLeft(),out_temp);
632 NodePair assign=flattenAssignmentNode(an,temp_left);
633 left.getEnd().addNext(assign.getBegin());
634 return new NodePair(left.getBegin(),assign.getEnd());
636 NodePair assign=flattenAssignmentNode(an,out_temp);
641 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
643 if (on.getRight()!=null) {
644 temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
645 right=flattenExpressionNode(on.getRight(),temp_right);
647 FlatNop nop=new FlatNop();
648 right=new NodePair(nop,nop);
651 if (op.getOp()==Operation.LOGIC_OR) {
652 /* Need to do shortcircuiting */
653 FlatCondBranch fcb=new FlatCondBranch(temp_left);
654 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
655 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
656 FlatNop fnop=new FlatNop();
657 left.getEnd().addNext(fcb);
658 fcb.addFalseNext(right.getBegin());
659 right.getEnd().addNext(fon2);
661 fcb.addTrueNext(fon1);
663 return new NodePair(left.getBegin(), fnop);
664 } else if (op.getOp()==Operation.LOGIC_AND) {
665 /* Need to do shortcircuiting */
666 FlatCondBranch fcb=new FlatCondBranch(temp_left);
667 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
668 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
669 FlatNop fnop=new FlatNop();
670 left.getEnd().addNext(fcb);
671 fcb.addTrueNext(right.getBegin());
672 right.getEnd().addNext(fon2);
674 fcb.addFalseNext(fon1);
676 return new NodePair(left.getBegin(), fnop);
679 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
680 left.getEnd().addNext(right.getBegin());
681 right.getEnd().addNext(fon);
682 return new NodePair(left.getBegin(),fon);
685 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
687 case Kind.AssignmentNode:
688 return flattenAssignmentNode((AssignmentNode)en,out_temp);
690 return flattenCastNode((CastNode)en,out_temp);
691 case Kind.CreateObjectNode:
692 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
693 case Kind.FieldAccessNode:
694 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
695 case Kind.ArrayAccessNode:
696 return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
697 case Kind.LiteralNode:
698 return flattenLiteralNode((LiteralNode)en,out_temp);
699 case Kind.MethodInvokeNode:
700 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
702 return flattenNameNode((NameNode)en,out_temp);
704 return flattenOpNode((OpNode)en,out_temp);
709 private NodePair flattenDeclarationNode(DeclarationNode dn) {
710 VarDescriptor vd=dn.getVarDescriptor();
711 TempDescriptor td=getTempforVar(vd);
712 if (dn.getExpression()!=null)
713 return flattenExpressionNode(dn.getExpression(),td);
715 FlatNop fn=new FlatNop();
716 return new NodePair(fn,fn);
720 private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
721 TagVarDescriptor tvd=dn.getTagVarDescriptor();
722 TagDescriptor tag=tvd.getTag();
723 TempDescriptor tmp=getTempforVar(tvd);
724 FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
725 return new NodePair(ftd,ftd);
728 private TempDescriptor getTempforParam(Descriptor d) {
729 if (temptovar.containsKey(d))
730 return (TempDescriptor)temptovar.get(d);
732 if (d instanceof VarDescriptor) {
733 VarDescriptor vd=(VarDescriptor)d;
734 TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
735 temptovar.put(vd,td);
737 } else if (d instanceof TagVarDescriptor) {
738 TagVarDescriptor tvd=(TagVarDescriptor)d;
739 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
740 TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
741 temptovar.put(tvd,td);
743 } else throw new Error("Unreconized Descriptor");
747 private TempDescriptor getTempforVar(Descriptor d) {
748 if (temptovar.containsKey(d))
749 return (TempDescriptor)temptovar.get(d);
751 if (d instanceof VarDescriptor) {
752 VarDescriptor vd=(VarDescriptor)d;
753 TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
754 temptovar.put(vd,td);
756 } else if (d instanceof TagVarDescriptor) {
757 TagVarDescriptor tvd=(TagVarDescriptor)d;
758 //BUGFIX TAGTYPE - add next line, modify following
759 //line to tag this new type descriptor, modify
760 //TempDescriptor constructor & factory to set type
761 //using this Type To test, use any program with tags
762 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
763 TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
764 temptovar.put(tvd,td);
766 } else throw new Error("Unrecognized Descriptor");
770 private NodePair flattenIfStatementNode(IfStatementNode isn) {
771 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
772 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
773 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
774 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
776 FlatNop nopend=new FlatNop();
778 if (isn.getFalseBlock()!=null)
779 false_np=flattenBlockNode(isn.getFalseBlock());
781 FlatNop nop=new FlatNop();
782 false_np=new NodePair(nop,nop);
785 cond.getEnd().addNext(fcb);
786 fcb.addTrueNext(true_np.getBegin());
787 fcb.addFalseNext(false_np.getBegin());
788 true_np.getEnd().addNext(nopend);
789 false_np.getEnd().addNext(nopend);
790 return new NodePair(cond.getBegin(), nopend);
793 private NodePair flattenLoopNode(LoopNode ln) {
794 if (ln.getType()==LoopNode.FORLOOP) {
795 NodePair initializer=flattenBlockNode(ln.getInitializer());
796 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
797 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
798 NodePair update=flattenBlockNode(ln.getUpdate());
799 NodePair body=flattenBlockNode(ln.getBody());
800 FlatNode begin=initializer.getBegin();
801 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
802 FlatNop nopend=new FlatNop();
803 FlatBackEdge backedge=new FlatBackEdge();
805 initializer.getEnd().addNext(condition.getBegin());
806 body.getEnd().addNext(update.getBegin());
807 update.getEnd().addNext(backedge);
808 backedge.addNext(condition.getBegin());
809 condition.getEnd().addNext(fcb);
810 fcb.addFalseNext(nopend);
811 fcb.addTrueNext(body.getBegin());
812 return new NodePair(begin,nopend);
813 } else if (ln.getType()==LoopNode.WHILELOOP) {
814 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
815 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
816 NodePair body=flattenBlockNode(ln.getBody());
817 FlatNode begin=condition.getBegin();
818 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
819 FlatNop nopend=new FlatNop();
820 FlatBackEdge backedge=new FlatBackEdge();
822 body.getEnd().addNext(backedge);
823 backedge.addNext(condition.getBegin());
825 condition.getEnd().addNext(fcb);
826 fcb.addFalseNext(nopend);
827 fcb.addTrueNext(body.getBegin());
828 return new NodePair(begin,nopend);
829 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
830 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
831 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
832 NodePair body=flattenBlockNode(ln.getBody());
833 FlatNode begin=body.getBegin();
834 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
835 FlatNop nopend=new FlatNop();
836 FlatBackEdge backedge=new FlatBackEdge();
838 body.getEnd().addNext(condition.getBegin());
839 condition.getEnd().addNext(fcb);
840 fcb.addFalseNext(nopend);
841 fcb.addTrueNext(backedge);
842 backedge.addNext(body.getBegin());
843 return new NodePair(begin,nopend);
844 } else throw new Error();
847 private NodePair flattenReturnNode(ReturnNode rntree) {
848 TempDescriptor retval=null;
850 if (rntree.getReturnExpression()!=null) {
851 retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
852 cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
855 FlatReturnNode rnflat=new FlatReturnNode(retval);
857 if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
858 MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
859 TempDescriptor thistd=getTempforVar(currmd.getThis());
860 FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
866 cond.getEnd().addNext(ln);
867 return new NodePair(cond.getBegin(),rnflat);
869 return new NodePair(ln,rnflat);
872 private NodePair flattenTaskExitNode(TaskExitNode ten) {
873 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
874 updateFlagActionNode(ffan, ten.getFlagEffects());
875 NodePair fcn=flattenConstraintCheck(ten.getChecks());
876 ffan.addNext(fcn.getBegin());
877 FlatReturnNode rnflat=new FlatReturnNode(null);
878 fcn.getEnd().addNext(rnflat);
879 return new NodePair(ffan, rnflat);
882 private NodePair flattenConstraintCheck(Vector ccs) {
883 FlatNode begin=new FlatNop();
885 return new NodePair(begin,begin);
887 for(int i=0;i<ccs.size();i++) {
888 ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
889 /* Flatten the arguments */
890 TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
891 String[] vars=new String[cc.numArgs()];
892 for(int j=0;j<cc.numArgs();j++) {
893 ExpressionNode en=cc.getArg(j);
894 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
896 vars[j]=cc.getVar(j);
897 NodePair np=flattenExpressionNode(en, td);
898 last.addNext(np.getBegin());
902 FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
906 return new NodePair(begin,last);
909 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
910 return flattenBlockNode(sbn.getBlockNode());
913 private NodePair flattenAtomicNode(AtomicNode sbn) {
914 NodePair np=flattenBlockNode(sbn.getBlockNode());
915 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
916 FlatAtomicExitNode faexn=new FlatAtomicExitNode();
917 faen.addNext(np.getBegin());
918 np.getEnd().addNext(faexn);
919 return new NodePair(faen, faexn);
922 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
924 case Kind.BlockExpressionNode:
925 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
927 case Kind.DeclarationNode:
928 return flattenDeclarationNode((DeclarationNode)bsn);
930 case Kind.TagDeclarationNode:
931 return flattenTagDeclarationNode((TagDeclarationNode)bsn);
933 case Kind.IfStatementNode:
934 return flattenIfStatementNode((IfStatementNode)bsn);
937 return flattenLoopNode((LoopNode)bsn);
939 case Kind.ReturnNode:
940 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
942 case Kind.TaskExitNode:
943 return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
945 case Kind.SubBlockNode:
946 return flattenSubBlockNode((SubBlockNode)bsn);
948 case Kind.AtomicNode:
949 return flattenAtomicNode((AtomicNode)bsn);