7 public class BuildFlat {
10 MethodDescriptor currmd;
17 // for synchronized blocks
18 Stack<TempDescriptor> lockStack;
20 // maps tree node to the set of flat node that is translated from the tree node
21 // WARNING: ONLY DID FOR NAMENODE NOW!
22 Hashtable<TreeNode,Set<FlatNode>> mapNode2FlatNodeSet;
24 public BuildFlat(State st, TypeUtil typeutil) {
26 temptovar=new Hashtable();
27 this.typeutil=typeutil;
28 this.breakset=new HashSet();
29 this.continueset=new HashSet();
30 this.lockStack = new Stack<TempDescriptor>();
31 this.mapNode2FlatNodeSet=new Hashtable<TreeNode,Set<FlatNode>>();
34 public Hashtable getMap() {
38 public void buildFlat() {
39 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
41 ClassDescriptor cn=(ClassDescriptor)it.next();
45 Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();
46 while(task_it.hasNext()) {
47 TaskDescriptor td=(TaskDescriptor)task_it.next();
52 private void flattenTask(TaskDescriptor td) {
53 BlockNode bn=state.getMethodBody(td);
54 NodePair np=flattenBlockNode(bn);
55 FlatNode fn=np.getBegin();
57 FlatNode fn2=np.getEnd();
59 if (fn2!=null&& fn2.kind()!=FKind.FlatReturnNode) {
60 FlatReturnNode rnflat=new FlatReturnNode(null);
65 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE);
66 ffan.setNumLine(bn.getNumLine());
69 FlatMethod fm=new FlatMethod(td, fe);
72 Hashtable visitedset=new Hashtable();
74 for(int i=0; i<td.numParameters(); i++) {
75 VarDescriptor paramvd=td.getParameter(i);
76 fm.addParameterTemp(getTempforVar(paramvd));
77 TagExpressionList tel=td.getTag(paramvd);
78 //BUG added next line to fix...to test feed in any task program
80 for(int j=0; j<tel.numTags(); j++) {
81 TagVarDescriptor tvd=(TagVarDescriptor) td.getParameterTable().getFromSameScope(tel.getName(j));
82 TempDescriptor tagtmp=getTempforVar(tvd);
83 if (!visitedset.containsKey(tvd.getName())) {
84 visitedset.put(tvd.getName(),tvd.getTag());
85 fm.addTagTemp(tagtmp);
87 TagDescriptor tmptd=(TagDescriptor) visitedset.get(tvd.getName());
88 if (!tmptd.equals(tvd.getTag()))
89 throw new Error("Two different tag types with same name as parameters to:"+td);
91 tel.setTemp(j, tagtmp);
95 /* Flatten Vector of Flag Effects */
96 Vector flags=td.getFlagEffects();
97 updateFlagActionNode(ffan,flags);
99 state.addFlatCode(td,fm);
103 /* This method transforms a vector of FlagEffects into the FlatFlagActionNode */
104 private void updateFlagActionNode(FlatFlagActionNode ffan, Vector flags) {
105 if (flags==null) // Do nothing if the flag effects vector is empty
108 for(int i=0; i<flags.size(); i++) {
109 FlagEffects fes=(FlagEffects)flags.get(i);
110 TempDescriptor flagtemp=getTempforVar(fes.getVar());
112 for(int j=0; j<fes.numEffects(); j++) {
113 FlagEffect fe=fes.getEffect(j);
114 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
117 for(int j=0; j<fes.numTagEffects(); j++) {
118 TagEffect te=fes.getTagEffect(j);
119 TempDescriptor tagtemp=getTempforVar(te.getTag());
121 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
126 FlatAtomicEnterNode curran=null;
128 private FlatNode spliceReturn(FlatNode fn) {
129 FlatReturnNode rnflat=null;
130 if (currmd.getReturnType()==null||currmd.getReturnType().isVoid()) {
131 rnflat=new FlatReturnNode(null);
134 TempDescriptor tmp=TempDescriptor.tempFactory("rettmp",currmd.getReturnType());
136 if (currmd.getReturnType().isPtr()) {
138 } else if (currmd.getReturnType().isByte()) {
140 } else if (currmd.getReturnType().isShort()) {
141 o=new Short((short)0);
142 } else if (currmd.getReturnType().isChar()) {
143 o=new Character('\0');
144 } else if (currmd.getReturnType().isInt()) {
146 } else if (currmd.getReturnType().isLong()) {
148 } else if (currmd.getReturnType().isBoolean()) {
149 o=new Boolean(false);
150 } else if (currmd.getReturnType().isFloat()) {
152 } else if (currmd.getReturnType().isDouble()) {
157 FlatLiteralNode fln=new FlatLiteralNode(currmd.getReturnType(),o,tmp);
158 rnflat=new FlatReturnNode(tmp);
165 private void flattenClass(ClassDescriptor cn) {
166 Iterator methodit=cn.getMethods();
167 while(methodit.hasNext()) {
168 flattenMethod(cn, (MethodDescriptor)methodit.next());
172 public void addJustFlatMethod(MethodDescriptor md) {
173 if (state.getMethodFlat(md)==null) {
174 FlatMethod fm=new FlatMethod(md, fe);
176 fm.addParameterTemp(getTempforParam(md.getThis()));
177 for(int i=0; i<md.numParameters(); i++) {
178 fm.addParameterTemp(getTempforParam(md.getParameter(i)));
180 state.addFlatCode(md,fm);
184 public void flattenMethod(ClassDescriptor cn, MethodDescriptor md) {
185 // if OOOJava is on, splice a special SESE in to
186 // enclose the main method
188 boolean spliceInImplicitMain = state.OOOJAVA && currmd.equals(typeutil.getMain() );
190 FlatSESEEnterNode spliceSESE = null;
191 FlatSESEExitNode spliceExit = null;
193 if( spliceInImplicitMain ) {
194 SESENode mainTree = new SESENode("main");
195 spliceSESE = new FlatSESEEnterNode(mainTree);
196 spliceExit = new FlatSESEExitNode(mainTree);
197 spliceSESE.setFlatExit(spliceExit);
198 spliceExit.setFlatEnter(spliceSESE);
199 spliceSESE.setIsMainSESE();
203 BlockNode bn=state.getMethodBody(currmd);
205 if (state.DSM&&currmd.getModifiers().isAtomic()) {
206 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
207 faen.setNumLine(bn.getNumLine());
211 if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
212 TempDescriptor thistd = null;
213 if(currmd.getModifiers().isStatic()) {
214 // need to lock the Class object
215 thistd=new TempDescriptor("classobj", cn);
218 thistd=getTempforVar(currmd.getThis());
220 if(!this.lockStack.isEmpty()) {
221 throw new Error("The lock stack for synchronized blocks/methods is not empty!");
223 this.lockStack.push(thistd);
225 NodePair np=flattenBlockNode(bn);
226 FlatNode fn=np.getBegin();
227 if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
230 this.lockStack.clear();
232 MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
233 FlatNode first = null;
237 if (lockStack.size()!=1) {
238 throw new Error("TOO MANY THINGS ON LOCKSTACK");
240 TempDescriptor thistd = this.lockStack.elementAt(0);
241 FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]);
242 fc.setNumLine(bn.getNumLine());
249 if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
250 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
251 while(!this.lockStack.isEmpty()) {
252 TempDescriptor thistd = this.lockStack.pop();
253 FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
254 fcunlock.setNumLine(bn.getNumLine());
255 end.addNext(fcunlock);
258 FlatNode rnflat=spliceReturn(end);
261 this.lockStack.clear();
264 } else if (state.DSM&&currmd.getModifiers().isAtomic()) {
267 if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
268 FlatAtomicExitNode aen=new FlatAtomicExitNode(curran);
269 np.getEnd().addNext(aen);
270 FlatNode rnflat=spliceReturn(aen);
273 } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
274 FlatNode rnflat=null;
275 if( spliceInImplicitMain ) {
276 np.getEnd().addNext(spliceExit);
277 rnflat=spliceReturn(spliceExit);
279 rnflat=spliceReturn(np.getEnd());
282 } else if (np.getEnd()!=null) {
283 if( spliceInImplicitMain ) {
284 FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
285 np.getEnd().addNext(spliceExit);
286 spliceExit.addNext(fe);
289 if( spliceInImplicitMain ) {
290 spliceSESE.addNext(fn);
294 FlatMethod fm=new FlatMethod(currmd, fe);
295 fm.setNumLine(bn.getNumLine());
297 if (!currmd.isStatic())
298 fm.addParameterTemp(getTempforParam(currmd.getThis()));
299 for(int i=0; i<currmd.numParameters(); i++) {
300 fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
302 state.addFlatCode(currmd,fm);
305 private NodePair flattenBlockNode(BlockNode bn) {
308 for(int i=0; i<bn.size(); i++) {
309 NodePair np=flattenBlockStatementNode(bn.get(i));
310 FlatNode np_begin=np.getBegin();
311 FlatNode np_end=np.getEnd();
318 end.addNext(np_begin);
320 return new NodePair(begin, null);
326 end=begin=new FlatNop();
328 return new NodePair(begin,end);
331 private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
332 //System.out.println("DEBUG -> inside flattenBlockExpressionNode\n");
333 TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
334 return flattenExpressionNode(en.getExpression(),tmp);
337 private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
338 TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
339 NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
340 FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
341 fcn.setNumLine(cn.getNumLine());
342 np.getEnd().addNext(fcn);
343 return new NodePair(np.getBegin(),fcn);
346 private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
347 FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
348 fln.setNumLine(ln.getNumLine());
349 return new NodePair(fln,fln);
352 private NodePair flattenOffsetNode(OffsetNode ofn, TempDescriptor out_temp) {
353 FlatOffsetNode fln = new FlatOffsetNode(ofn.getClassType(), ofn.getField(), out_temp);
354 fln.setNumLine(ofn.getNumLine());
355 return new NodePair(fln, fln);
358 private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
359 TypeDescriptor td=con.getType();
361 FlatNode fn=new FlatNew(td, out_temp, con.isGlobal(), con.getDisjointId());
363 //handle wrapper fields
364 ClassDescriptor cd=td.getClassDesc();
365 for(Iterator fieldit=cd.getFields(); fieldit.hasNext(); ) {
366 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
367 if (fd.getType().iswrapper()) {
368 TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType());
369 FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal());
370 fnwrapper.setNumLine(con.getNumLine());
371 FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp);
372 fsfn.setNumLine(con.getNumLine());
373 last.addNext(fnwrapper);
374 fnwrapper.addNext(fsfn);
379 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
382 for(int i=0; i<con.numArgs(); i++) {
383 ExpressionNode en=con.getArg(i);
384 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
386 NodePair np=flattenExpressionNode(en, tmp);
387 last.addNext(np.getBegin());
390 MethodDescriptor md=con.getConstructor();
391 //Call to constructor
392 FlatCall fc=new FlatCall(md, null, out_temp, temps);
393 fc.setNumLine(con.getNumLine());
396 if (td.getClassDesc().hasFlags()) {
397 // if (con.getFlagEffects()!=null) {
398 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
399 ffan.setNumLine(con.getNumLine());
400 FlagEffects fes=con.getFlagEffects();
401 TempDescriptor flagtemp=out_temp;
403 for(int j=0; j<fes.numEffects(); j++) {
404 FlagEffect fe=fes.getEffect(j);
405 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
407 for(int j=0; j<fes.numTagEffects(); j++) {
408 TagEffect te=fes.getTagEffect(j);
409 TempDescriptor tagtemp=getTempforVar(te.getTag());
411 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
414 ffan.addFlagAction(flagtemp, null, false);
419 return new NodePair(fn,last);
421 if(con.getArrayInitializer() == null) {
424 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
425 for (int i=0; i<con.numArgs(); i++) {
426 ExpressionNode en=con.getArg(i);
427 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
429 NodePair np=flattenExpressionNode(en, tmp);
433 last.addNext(np.getBegin());
436 TempDescriptor tmp2=(i==0)?
438 TempDescriptor.tempFactory("arg",en.getType());
440 FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal(), con.getDisjointId());
442 if (temps.length>1) {
443 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
444 fn.addNext(np.getBegin());
445 return new NodePair(first,np.getEnd());
446 } else if (td.isArray()&&td.dereference().iswrapper()) {
447 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
448 fn.addNext(np.getBegin());
449 return new NodePair(first,np.getEnd());
451 return new NodePair(first, fn);
453 // array creation with initializers
454 return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
459 private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
460 TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
461 TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
462 FlatNop fnop=new FlatNop(); //last node
465 FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
467 FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
469 TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
471 FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
472 FlatCondBranch fcb=new FlatCondBranch(tmpbool);
473 fcb.setTrueProb(State.TRUEPROB);
476 TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
477 FlatNew fn=td.iswrapper()?new FlatNew(td, new_tmp, isglobal):new FlatNew(td, new_tmp, temparray[i+1], isglobal);
478 FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
480 FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
486 fcb.addFalseNext(fnop);
488 //Recursive call here
489 if ((i+2)<temparray.length) {
490 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
491 fsen.addNext(np2.getBegin());
492 np2.getEnd().addNext(fon);
493 } else if (td.isArray()&&td.dereference().iswrapper()) {
494 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
495 fsen.addNext(np2.getBegin());
496 np2.getEnd().addNext(fon);
501 return new NodePair(fln, fnop);
504 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
505 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
508 TempDescriptor thisarg=null;
510 if (min.getExpression()!=null) {
511 TypeDescriptor mtd = min.getExpression().getType();
512 if(mtd.isClass() && mtd.getClassDesc().isEnum()) {
513 mtd = new TypeDescriptor(TypeDescriptor.INT);
515 thisarg=TempDescriptor.tempFactory("thisarg", mtd);
516 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
522 for(int i=0; i<min.numArgs(); i++) {
523 ExpressionNode en=min.getArg(i);
524 TypeDescriptor etd = en.getType();
525 if(etd.isClass() && etd.getClassDesc().isEnum()) {
526 etd = new TypeDescriptor(TypeDescriptor.INT);
528 TempDescriptor td=TempDescriptor.tempFactory("arg", etd);
530 NodePair np=flattenExpressionNode(en, td);
534 last.addNext(np.getBegin());
538 MethodDescriptor md=min.getMethod();
540 //Call to constructor
543 if(md.getReturnType()==null||md.getReturnType().isVoid())
544 fc=new FlatCall(md, null, thisarg, temps, min.getSuper());
546 fc=new FlatCall(md, out_temp, thisarg, temps, min.getSuper());
548 fc.setNumLine(min.getNumLine());
554 return new NodePair(first,fc);
557 private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
558 TempDescriptor tmp=null;
559 if(fan.getExpression().getType().isClassNameRef()) {
560 // static field dereference with class name
561 tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType());
562 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
563 fn.setNumLine(fan.getNumLine());
564 return new NodePair(fn,fn);
566 tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
567 NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
568 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
569 fn.setNumLine(fan.getNumLine());
570 npe.getEnd().addNext(fn);
571 return new NodePair(npe.getBegin(),fn);
575 private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
576 TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
577 TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
578 NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
579 NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
580 TempDescriptor arraytmp=out_temp;
581 if (aan.iswrapper()) {
583 arraytmp=TempDescriptor.tempFactory("temp", aan.getExpression().getType().dereference());
585 FlatNode fn=new FlatElementNode(tmp,tmpindex,arraytmp);
586 fn.setNumLine(aan.getNumLine());
587 npe.getEnd().addNext(npi.getBegin());
588 npi.getEnd().addNext(fn);
589 if (aan.iswrapper()) {
590 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)aan.getExpression().getType().dereference().getClassDesc().getFieldTable().get("value"),arraytmp,out_temp);
591 ffn.setNumLine(aan.getNumLine());
595 return new NodePair(npe.getBegin(),fn);
598 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
600 // left side is variable
601 // left side is field
602 // left side is array
604 Operation base=an.getOperation().getBaseOp();
605 boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC);
608 //rewrite the base operation
609 base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB);
613 TempDescriptor src_tmp = src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType());
616 if (an.getSrc()!=null) {
617 if(an.getSrc().getEval() != null) {
618 FlatLiteralNode fln=new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
619 fln.setNumLine(an.getSrc().getNumLine());
622 NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
623 first=np_src.getBegin();
624 last=np_src.getEnd();
627 FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
628 fln.setNumLine(an.getNumLine());
633 if (an.getDest().kind()==Kind.FieldAccessNode) {
634 //We are assigning an object field
636 FieldAccessNode fan=(FieldAccessNode)an.getDest();
637 ExpressionNode en=fan.getExpression();
638 TempDescriptor dst_tmp=null;
639 NodePair np_baseexp=null;
640 if(en.getType().isClassNameRef()) {
641 // static field dereference with class name
642 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
643 FlatNop nop=new FlatNop();
644 np_baseexp = new NodePair(nop,nop);
646 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
647 np_baseexp=flattenExpressionNode(en, dst_tmp);
650 first=np_baseexp.getBegin();
652 last.addNext(np_baseexp.getBegin());
653 last=np_baseexp.getEnd();
655 //See if we need to perform an operation
657 //If it is a preinc we need to store the initial value
658 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
659 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
660 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
661 ffn.setNumLine(an.getNumLine());
665 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
666 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
667 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
668 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
669 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
670 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
671 fc1.setNumLine(an.getNumLine());
673 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
674 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
675 fc.setNumLine(an.getNumLine());
681 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
682 fon.setNumLine(an.getNumLine());
689 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
690 fsfn.setNumLine(en.getNumLine());
691 addMapNode2FlatNodeSet(an,fsfn);
695 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
696 fon2.setNumLine(an.getNumLine());
700 return new NodePair(first, last);
701 } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
702 //We are assigning an array element
704 ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
705 ExpressionNode en=aan.getExpression();
706 ExpressionNode enindex=aan.getIndex();
707 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
708 TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
709 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
710 NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
712 first=np_baseexp.getBegin();
714 last.addNext(np_baseexp.getBegin());
715 np_baseexp.getEnd().addNext(np_indexexp.getBegin());
716 last=np_indexexp.getEnd();
718 //See if we need to perform an operation
720 //If it is a preinc we need to store the initial value
721 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
722 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
724 if (aan.iswrapper()) {
725 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
726 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
727 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
728 fen.setNumLine(aan.getNumLine());
729 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp3,src_tmp2);
730 ffn.setNumLine(aan.getNumLine());
735 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
736 fen.setNumLine(aan.getNumLine());
740 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
741 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
742 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
743 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
744 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
745 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
746 fc1.setNumLine(an.getNumLine());
748 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
749 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
750 fc.setNumLine(an.getNumLine());
757 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
758 fon.setNumLine(an.getNumLine());
765 if (aan.iswrapper()) {
766 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
767 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
768 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
769 fen.setNumLine(aan.getNumLine());
770 FlatSetFieldNode fsfn=new FlatSetFieldNode(src_tmp3,(FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp);
771 fsfn.setNumLine(aan.getExpression().getNumLine());
776 FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
777 fsen.setNumLine(aan.getNumLine());
782 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
783 fon2.setNumLine(an.getNumLine());
787 addMapNode2FlatNodeSet(an,last);
788 return new NodePair(first, last);
789 } else if (an.getDest().kind()==Kind.NameNode) {
790 //We could be assigning a field or variable
791 NameNode nn=(NameNode)an.getDest();
794 if (nn.getExpression()!=null) {
796 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
797 ExpressionNode en=fan.getExpression();
798 TempDescriptor dst_tmp=null;
799 NodePair np_baseexp=null;
800 if(en.getType().isClassNameRef()) {
801 // static field dereference with class name
802 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
803 FlatNop nop=new FlatNop();
804 np_baseexp = new NodePair(nop,nop);
806 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
807 np_baseexp=flattenExpressionNode(en, dst_tmp);
810 first=np_baseexp.getBegin();
812 last.addNext(np_baseexp.getBegin());
813 last=np_baseexp.getEnd();
815 //See if we need to perform an operation
817 //If it is a preinc we need to store the initial value
818 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
819 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
821 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
822 ffn.setNumLine(an.getNumLine());
827 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
828 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
829 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
830 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
831 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
832 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
833 fc1.setNumLine(an.getNumLine());
835 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
836 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
837 fc.setNumLine(an.getNumLine());
843 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
844 fon.setNumLine(an.getNumLine());
852 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
853 fsfn.setNumLine(en.getNumLine());
854 addMapNode2FlatNodeSet(an,fsfn);
858 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
859 fon2.setNumLine(an.getNumLine());
863 return new NodePair(first, last);
865 if (nn.getField()!=null) {
869 //See if we need to perform an operation
871 //If it is a preinc we need to store the initial value
872 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
873 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
875 TempDescriptor ftmp= null;
876 if((nn.getClassDesc() != null)) {
877 // this is a static field
878 ftmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
881 ftmp=getTempforVar(nn.getVar());
883 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), ftmp, src_tmp2);
884 ffn.setNumLine(an.getNumLine());
894 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
895 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
896 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
897 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
898 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
899 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
900 fc1.setNumLine(an.getNumLine());
902 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
903 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
904 fc.setNumLine(an.getNumLine());
910 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
911 fon.setNumLine(an.getNumLine());
918 FlatSetFieldNode fsfn=null;
919 if(nn.getClassDesc()!=null) {
920 // this is a static field access inside of a static block
921 fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
922 fsfn.setNumLine(nn.getNumLine());
924 fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
925 fsfn.setNumLine(nn.getNumLine());
927 addMapNode2FlatNodeSet(an,fsfn);
935 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
936 fon2.setNumLine(an.getNumLine());
940 return new NodePair(first, last);
943 //See if we need to perform an operation
946 //If it is a preinc we need to store the initial value
947 TempDescriptor src_tmp2=getTempforVar(nn.getVar());
948 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
950 FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
951 fon.setNumLine(an.getNumLine());
960 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
961 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
962 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
963 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
964 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
965 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
966 fc1.setNumLine(an.getNumLine());
968 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
969 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
970 fc.setNumLine(an.getNumLine());
981 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
982 fon.setNumLine(an.getNumLine());
992 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
993 fon.setNumLine(an.getNumLine());
994 addMapNode2FlatNodeSet(an,fon);
999 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
1000 fon2.setNumLine(an.getNumLine());
1004 return new NodePair(first, last);
1012 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
1013 if (nn.getExpression()!=null) {
1014 /* Hack - use subtree instead */
1015 return flattenExpressionNode(nn.getExpression(),out_temp);
1016 } else if (nn.getField()!=null) {
1017 TempDescriptor tmp= null;
1018 if((nn.getClassDesc() != null)) {
1019 // this is a static field
1020 tmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
1023 tmp=getTempforVar(nn.getVar());
1025 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
1026 ffn.setNumLine(nn.getNumLine());
1027 addMapNode2FlatNodeSet(nn,ffn);
1028 return new NodePair(ffn,ffn);
1030 TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
1033 out_temp.setTag(tmp.getTag());
1035 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
1036 fon.setNumLine(nn.getNumLine());
1037 addMapNode2FlatNodeSet(nn,fon);
1038 return new NodePair(fon,fon);
1042 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
1043 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
1044 TempDescriptor temp_right=null;
1046 Operation op=on.getOp();
1048 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
1050 if (on.getRight()!=null) {
1051 temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
1052 right=flattenExpressionNode(on.getRight(),temp_right);
1054 FlatNop nop=new FlatNop();
1055 right=new NodePair(nop,nop);
1058 if (op.getOp()==Operation.LOGIC_OR) {
1059 /* Need to do shortcircuiting */
1060 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1061 fcb.setNumLine(on.getNumLine());
1062 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1063 fon1.setNumLine(on.getNumLine());
1064 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1065 fon2.setNumLine(on.getNumLine());
1066 FlatNop fnop=new FlatNop();
1067 left.getEnd().addNext(fcb);
1068 fcb.addFalseNext(right.getBegin());
1069 right.getEnd().addNext(fon2);
1071 fcb.addTrueNext(fon1);
1073 return new NodePair(left.getBegin(), fnop);
1074 } else if (op.getOp()==Operation.LOGIC_AND) {
1075 /* Need to do shortcircuiting */
1076 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1077 fcb.setNumLine(on.getNumLine());
1078 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1079 fon1.setNumLine(on.getNumLine());
1080 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1081 fon2.setNumLine(on.getNumLine());
1082 FlatNop fnop=new FlatNop();
1083 left.getEnd().addNext(fcb);
1084 fcb.addTrueNext(right.getBegin());
1085 right.getEnd().addNext(fon2);
1087 fcb.addFalseNext(fon1);
1089 return new NodePair(left.getBegin(), fnop);
1090 } else if (op.getOp()==Operation.ADD&&on.getLeft().getType().isString()) {
1091 //We have a string concatenate
1092 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
1093 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
1094 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
1095 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
1096 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {temp_left});
1097 fc1.setNumLine(on.getNumLine());
1099 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
1100 FlatCall fc=new FlatCall(concatmd, out_temp, src_tmp3, new TempDescriptor[] {temp_right});
1101 fc.setNumLine(on.getNumLine());
1102 left.getEnd().addNext(right.getBegin());
1103 right.getEnd().addNext(fc1);
1105 return new NodePair(left.getBegin(), fc);
1108 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
1109 fon.setNumLine(on.getNumLine());
1110 left.getEnd().addNext(right.getBegin());
1111 right.getEnd().addNext(fon);
1112 return new NodePair(left.getBegin(),fon);
1115 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
1117 case Kind.AssignmentNode:
1118 return flattenAssignmentNode((AssignmentNode)en,out_temp);
1121 return flattenCastNode((CastNode)en,out_temp);
1123 case Kind.CreateObjectNode:
1124 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
1126 case Kind.FieldAccessNode:
1127 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
1129 case Kind.ArrayAccessNode:
1130 return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
1132 case Kind.LiteralNode:
1133 return flattenLiteralNode((LiteralNode)en,out_temp);
1135 case Kind.MethodInvokeNode:
1136 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
1139 return flattenNameNode((NameNode)en,out_temp);
1142 return flattenOpNode((OpNode)en,out_temp);
1144 case Kind.OffsetNode:
1145 return flattenOffsetNode((OffsetNode)en,out_temp);
1147 case Kind.TertiaryNode:
1148 return flattenTertiaryNode((TertiaryNode)en,out_temp);
1150 case Kind.InstanceOfNode:
1151 return flattenInstanceOfNode((InstanceOfNode)en,out_temp);
1153 case Kind.ArrayInitializerNode:
1154 return flattenArrayInitializerNode((ArrayInitializerNode)en,out_temp);
1159 private NodePair flattenDeclarationNode(DeclarationNode dn) {
1160 VarDescriptor vd=dn.getVarDescriptor();
1161 TempDescriptor td=getTempforVar(vd);
1162 if (dn.getExpression()!=null)
1163 return flattenExpressionNode(dn.getExpression(),td);
1165 FlatNop fn=new FlatNop();
1166 return new NodePair(fn,fn);
1170 private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
1171 TagVarDescriptor tvd=dn.getTagVarDescriptor();
1172 TagDescriptor tag=tvd.getTag();
1173 TempDescriptor tmp=getTempforVar(tvd);
1174 FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
1175 ftd.setNumLine(dn.getNumLine());
1176 return new NodePair(ftd,ftd);
1179 private TempDescriptor getTempforParam(Descriptor d) {
1180 if (temptovar.containsKey(d))
1181 return (TempDescriptor)temptovar.get(d);
1183 if (d instanceof VarDescriptor) {
1184 VarDescriptor vd=(VarDescriptor)d;
1185 TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
1186 temptovar.put(vd,td);
1188 } else if (d instanceof TagVarDescriptor) {
1189 TagVarDescriptor tvd=(TagVarDescriptor)d;
1190 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1191 TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
1192 temptovar.put(tvd,td);
1194 } else throw new Error("Unreconized Descriptor");
1198 private TempDescriptor getTempforVar(Descriptor d) {
1199 if (temptovar.containsKey(d))
1200 return (TempDescriptor)temptovar.get(d);
1202 if (d instanceof VarDescriptor) {
1203 VarDescriptor vd=(VarDescriptor)d;
1204 TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
1205 temptovar.put(vd,td);
1207 } else if (d instanceof TagVarDescriptor) {
1208 TagVarDescriptor tvd=(TagVarDescriptor)d;
1209 //BUGFIX TAGTYPE - add next line, modify following
1210 //line to tag this new type descriptor, modify
1211 //TempDescriptor constructor & factory to set type
1212 //using this Type To test, use any program with tags
1213 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1214 TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
1215 temptovar.put(tvd,td);
1217 } else throw new Error("Unrecognized Descriptor");
1221 private NodePair flattenIfStatementNode(IfStatementNode isn) {
1222 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1223 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
1224 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1225 fcb.setNumLine(isn.getNumLine());
1226 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
1228 FlatNop nopend=new FlatNop();
1230 if (isn.getFalseBlock()!=null)
1231 false_np=flattenBlockNode(isn.getFalseBlock());
1233 FlatNop nop=new FlatNop();
1234 false_np=new NodePair(nop,nop);
1237 cond.getEnd().addNext(fcb);
1238 fcb.addTrueNext(true_np.getBegin());
1239 fcb.addFalseNext(false_np.getBegin());
1240 if (true_np.getEnd()!=null)
1241 true_np.getEnd().addNext(nopend);
1242 if (false_np.getEnd()!=null)
1243 false_np.getEnd().addNext(nopend);
1244 if (nopend.numPrev()==0)
1245 return new NodePair(cond.getBegin(), null);
1247 return new NodePair(cond.getBegin(), nopend);
1250 private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
1251 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
1252 NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
1253 NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp);
1255 cond.getEnd().addNext(sbody.getBegin());
1257 return new NodePair(cond.getBegin(), sbody.getEnd());
1260 private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp) {
1261 FlatNode begin=null;
1263 NodePair prev_true_branch = null;
1264 NodePair prev_false_branch = null;
1265 for(int i=0; i<bn.size(); i++) {
1266 SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
1267 HashSet oldbs=breakset;
1268 breakset=new HashSet();
1270 NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
1271 Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
1272 FlatNode cond_begin = null;
1273 NodePair prev_fnp = null;
1274 for(int j = 0; j < slnv.size(); j++) {
1275 SwitchLabelNode sln = slnv.elementAt(j);
1276 NodePair left = null;
1277 NodePair false_np = null;
1278 if(sln.isDefault()) {
1281 TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1282 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
1283 Operation op=new Operation(Operation.EQUAL);
1284 left=flattenExpressionNode(sln.getCondition(), temp_left);
1285 FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
1286 fon.setNumLine(sln.getNumLine());
1287 left.getEnd().addNext(fon);
1289 FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
1290 fcb.setNumLine(bn.getNumLine());
1291 fcb.setTrueProb(State.TRUEPROB);
1293 FlatNop nop=new FlatNop();
1294 false_np=new NodePair(nop,nop);
1297 fcb.addTrueNext(body.getBegin());
1298 fcb.addFalseNext(false_np.getBegin());
1300 if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
1301 prev_fnp.getEnd().addNext(left.getBegin());
1303 prev_fnp = false_np;
1306 begin = left.getBegin();
1308 if(cond_begin == null) {
1309 cond_begin = left.getBegin();
1312 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1313 prev_false_branch.getEnd().addNext(cond_begin);
1315 prev_false_branch = prev_fnp;
1316 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1317 prev_true_branch.getEnd().addNext(body.getBegin());
1319 prev_true_branch = body;
1320 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1321 FlatNode fn=(FlatNode)breakit.next();
1329 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1332 prev_true_branch.getEnd().addNext(end);
1334 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1337 prev_false_branch.getEnd().addNext(end);
1340 end=begin=new FlatNop();
1342 return new NodePair(begin,end);
1345 private NodePair flattenLoopNode(LoopNode ln) {
1347 HashSet oldbs=breakset;
1348 HashSet oldcs=continueset;
1349 breakset=new HashSet();
1350 continueset=new HashSet();
1352 if (ln.getType()==LoopNode.FORLOOP) {
1353 NodePair initializer=flattenBlockNode(ln.getInitializer());
1354 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1355 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1356 NodePair update=flattenBlockNode(ln.getUpdate());
1357 NodePair body=flattenBlockNode(ln.getBody());
1358 FlatNode begin=initializer.getBegin();
1359 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1360 fcb.setNumLine(ln.getNumLine());
1361 fcb.setTrueProb(State.TRUEPROB);
1363 fcb.setLoopEntrance(condition.getBegin());
1364 FlatNop nopend=new FlatNop();
1365 FlatBackEdge backedge=new FlatBackEdge();
1367 FlatNop nop2=new FlatNop();
1368 initializer.getEnd().addNext(nop2);
1369 nop2.addNext(condition.getBegin());
1370 if (body.getEnd()!=null)
1371 body.getEnd().addNext(update.getBegin());
1372 update.getEnd().addNext(backedge);
1373 backedge.addNext(condition.getBegin());
1374 condition.getEnd().addNext(fcb);
1375 fcb.addFalseNext(nopend);
1376 fcb.addTrueNext(body.getBegin());
1377 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1378 FlatNode fn=(FlatNode)contit.next();
1380 fn.addNext(update.getBegin());
1382 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1383 FlatNode fn=(FlatNode)breakit.next();
1389 if(ln.getLabel()!=null){
1390 state.fn2labelMap.put(condition.getBegin(), ln.getLabel());
1392 return new NodePair(begin,nopend);
1393 } else if (ln.getType()==LoopNode.WHILELOOP) {
1394 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1395 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1396 NodePair body=flattenBlockNode(ln.getBody());
1397 FlatNode begin=condition.getBegin();
1398 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1399 fcb.setNumLine(ln.getNumLine());
1400 fcb.setTrueProb(State.TRUEPROB);
1402 fcb.setLoopEntrance(begin);
1403 FlatNop nopend=new FlatNop();
1404 FlatBackEdge backedge=new FlatBackEdge();
1406 if (body.getEnd()!=null)
1407 body.getEnd().addNext(backedge);
1408 backedge.addNext(condition.getBegin());
1410 condition.getEnd().addNext(fcb);
1411 fcb.addFalseNext(nopend);
1412 fcb.addTrueNext(body.getBegin());
1414 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1415 FlatNode fn=(FlatNode)contit.next();
1417 fn.addNext(backedge);
1419 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1420 FlatNode fn=(FlatNode)breakit.next();
1426 if(ln.getLabel()!=null){
1427 state.fn2labelMap.put(begin, ln.getLabel());
1429 return new NodePair(begin,nopend);
1430 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
1431 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1432 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1433 NodePair body=flattenBlockNode(ln.getBody());
1434 FlatNode begin=body.getBegin();
1435 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1436 fcb.setNumLine(ln.getNumLine());
1437 fcb.setTrueProb(State.TRUEPROB);
1439 fcb.setLoopEntrance(begin);
1440 FlatNop nopend=new FlatNop();
1441 FlatBackEdge backedge=new FlatBackEdge();
1443 if (body.getEnd()!=null)
1444 body.getEnd().addNext(condition.getBegin());
1445 condition.getEnd().addNext(fcb);
1446 fcb.addFalseNext(nopend);
1447 fcb.addTrueNext(backedge);
1448 backedge.addNext(body.getBegin());
1450 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1451 FlatNode fn=(FlatNode)contit.next();
1453 fn.addNext(condition.getBegin());
1455 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1456 FlatNode fn=(FlatNode)breakit.next();
1462 if(ln.getLabel()!=null){
1463 state.fn2labelMap.put(begin, ln.getLabel());
1465 return new NodePair(begin,nopend);
1466 } else throw new Error();
1469 private NodePair flattenReturnNode(ReturnNode rntree) {
1470 TempDescriptor retval=null;
1472 if (rntree.getReturnExpression()!=null) {
1473 retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
1474 cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
1477 FlatReturnNode rnflat=new FlatReturnNode(retval);
1478 rnflat.setNumLine(rntree.getNumLine());
1481 if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
1483 //XXXXXXXXX: FIX THIS
1485 FlatNode end = null;
1486 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1487 for(int j = this.lockStack.size(); j > 0; j--) {
1488 TempDescriptor thistd = this.lockStack.elementAt(j-1);
1489 FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
1490 fcunlock.setNumLine(rntree.getNumLine());
1492 end.addNext(fcunlock);
1500 if (state.DSM&&currmd.getModifiers().isAtomic()) {
1501 FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
1507 cond.getEnd().addNext(ln);
1508 return new NodePair(cond.getBegin(),null);
1510 return new NodePair(ln,null);
1513 private NodePair flattenTaskExitNode(TaskExitNode ten) {
1514 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
1515 ffan.setTaskExitIndex(ten.getTaskExitIndex());
1516 updateFlagActionNode(ffan, ten.getFlagEffects());
1517 NodePair fcn=flattenConstraintCheck(ten.getChecks());
1518 ffan.addNext(fcn.getBegin());
1519 FlatReturnNode rnflat=new FlatReturnNode(null);
1520 rnflat.setNumLine(ten.getNumLine());
1522 fcn.getEnd().addNext(rnflat);
1523 return new NodePair(ffan, null);
1526 private NodePair flattenConstraintCheck(Vector ccs) {
1527 FlatNode begin=new FlatNop();
1529 return new NodePair(begin,begin);
1530 FlatNode last=begin;
1531 for(int i=0; i<ccs.size(); i++) {
1532 ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
1533 /* Flatten the arguments */
1534 TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
1535 String[] vars=new String[cc.numArgs()];
1536 for(int j=0; j<cc.numArgs(); j++) {
1537 ExpressionNode en=cc.getArg(j);
1538 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
1540 vars[j]=cc.getVar(j);
1541 NodePair np=flattenExpressionNode(en, td);
1542 last.addNext(np.getBegin());
1546 FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
1550 return new NodePair(begin,last);
1553 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
1554 return flattenBlockNode(sbn.getBlockNode());
1557 private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
1558 TempDescriptor montmp=null;
1559 FlatNode first = null;
1560 FlatNode end = null;
1561 if(sbn.getExpr() instanceof ClassTypeNode) {
1562 montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
1564 montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
1565 NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
1566 first = npexp.getBegin();
1567 end = npexp.getEnd();
1569 this.lockStack.push(montmp);
1570 NodePair npblock=flattenBlockNode(sbn.getBlockNode());
1572 this.lockStack.pop();
1575 MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
1576 FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
1577 fcen.setNumLine(sbn.getNumLine());
1579 MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1580 FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
1581 fcex.setNumLine(sbn.getNumLine());
1583 this.lockStack.pop();
1590 fcen.addNext(npblock.getBegin());
1592 if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
1593 npblock.getEnd().addNext(fcex);
1594 return new NodePair(first, fcex);
1596 return new NodePair(first, null);
1601 private NodePair flattenAtomicNode(AtomicNode sbn) {
1602 NodePair np=flattenBlockNode(sbn.getBlockNode());
1603 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
1604 faen.setNumLine(sbn.getNumLine());
1605 FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
1606 faen.addNext(np.getBegin());
1607 np.getEnd().addNext(faexn);
1608 return new NodePair(faen, faexn);
1611 private NodePair flattenGenReachNode(GenReachNode grn) {
1612 FlatGenReachNode fgrn = new FlatGenReachNode(grn.getGraphName() );
1613 return new NodePair(fgrn, fgrn);
1616 private NodePair flattenGenDefReachNode(GenDefReachNode gdrn) {
1617 FlatGenDefReachNode fgdrn = new FlatGenDefReachNode(gdrn.getOutputName() );
1618 return new NodePair(fgdrn, fgdrn);
1621 private NodePair flattenSESENode(SESENode sn) {
1622 if( sn.isStart() ) {
1623 FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
1624 fsen.setNumLine(sn.getNumLine());
1625 sn.setFlatEnter(fsen);
1626 return new NodePair(fsen, fsen);
1629 FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
1630 sn.setFlatExit(fsexn);
1631 FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
1632 fsexn.setFlatEnter(fsen);
1633 sn.getStart().getFlatEnter().setFlatExit(fsexn);
1635 return new NodePair(fsexn, fsexn);
1638 private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
1639 FlatNop fn=new FlatNop();
1643 continueset.add(fn);
1644 return new NodePair(fn,null);
1647 private NodePair flattenInstanceOfNode(InstanceOfNode tn, TempDescriptor out_temp) {
1648 TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
1649 NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
1650 FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
1651 fion.setNumLine(tn.getNumLine());
1652 cond.getEnd().addNext(fion);
1653 return new NodePair(cond.getBegin(),fion);
1656 private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
1657 boolean isGlobal = false;
1658 String disjointId = null;
1659 // get the type the array to be initialized
1660 TypeDescriptor td = ain.getType();
1662 // create a new array of size equal to the array initializer
1663 FlatNode first=null;
1665 TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
1666 FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
1667 fln_tmp.setNumLine(ain.getNumLine());
1668 first = last=fln_tmp;
1670 // create the new array
1671 FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
1675 // initialize the new array
1676 for(int i = 0; i < ain.numVarInitializers(); i++) {
1677 ExpressionNode var_init_node = ain.getVarInitializer(i);
1678 TempDescriptor tmp_toinit = out_temp;
1679 TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
1681 TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
1682 FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
1683 fln.setNumLine(ain.getNumLine());
1684 // calculate the initial value
1685 NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
1686 // TODO wrapper class process is missing now
1687 /*if(td.isArray() && td.dereference().iswrapper()) {
1689 FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
1690 fsen.setNumLine(ain.getNumLine());
1692 fln.addNext(np_init.getBegin());
1693 np_init.getEnd().addNext(fsen);
1697 return new NodePair(first, last);
1700 private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
1701 TempDescriptor cond_temp=TempDescriptor.tempFactory("tert_cond",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1702 TempDescriptor true_temp=TempDescriptor.tempFactory("tert_true",tn.getTrueExpr().getType());
1703 TempDescriptor fals_temp=TempDescriptor.tempFactory("tert_fals",tn.getFalseExpr().getType());
1705 NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
1706 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1707 fcb.setNumLine(tn.getNumLine());
1709 NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
1710 FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
1711 fonT.setNumLine(tn.getNumLine());
1713 NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
1714 FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
1715 fonF.setNumLine(tn.getNumLine());
1717 FlatNop nopend=new FlatNop();
1719 cond.getEnd().addNext(fcb);
1721 fcb.addTrueNext(trueExpr.getBegin());
1722 fcb.addFalseNext(falseExpr.getBegin());
1724 trueExpr.getEnd().addNext(fonT);
1725 fonT.addNext(nopend);
1727 falseExpr.getEnd().addNext(fonF);
1728 fonF.addNext(nopend);
1730 return new NodePair(cond.getBegin(), nopend);
1733 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
1734 switch(bsn.kind()) {
1735 case Kind.BlockExpressionNode:
1736 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
1738 case Kind.DeclarationNode:
1739 return flattenDeclarationNode((DeclarationNode)bsn);
1741 case Kind.TagDeclarationNode:
1742 return flattenTagDeclarationNode((TagDeclarationNode)bsn);
1744 case Kind.IfStatementNode:
1745 return flattenIfStatementNode((IfStatementNode)bsn);
1747 case Kind.SwitchStatementNode:
1748 return flattenSwitchStatementNode((SwitchStatementNode)bsn);
1751 return flattenLoopNode((LoopNode)bsn);
1753 case Kind.ReturnNode:
1754 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
1756 case Kind.TaskExitNode:
1757 return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
1759 case Kind.SubBlockNode:
1760 return flattenSubBlockNode((SubBlockNode)bsn);
1762 case Kind.AtomicNode:
1763 return flattenAtomicNode((AtomicNode)bsn);
1765 case Kind.SynchronizedNode:
1766 return flattenSynchronizedNode((SynchronizedNode)bsn);
1769 return flattenSESENode((SESENode)bsn);
1771 case Kind.GenReachNode:
1772 return flattenGenReachNode((GenReachNode)bsn);
1774 case Kind.GenDefReachNode:
1775 return flattenGenDefReachNode((GenDefReachNode)bsn);
1777 case Kind.ContinueBreakNode:
1778 return flattenContinueBreakNode((ContinueBreakNode)bsn);
1783 private void addMapNode2FlatNodeSet(TreeNode tn, FlatNode fn){
1784 Set<FlatNode> fnSet=mapNode2FlatNodeSet.get(tn);
1786 fnSet=new HashSet<FlatNode>();
1787 mapNode2FlatNodeSet.put(tn, fnSet);
1792 public Set<FlatNode> getFlatNodeSet(TreeNode tn){
1793 // WARNING: ONLY DID FOR NAMENODE NOW!
1794 assert(tn instanceof NameNode);
1795 return mapNode2FlatNodeSet.get(tn);