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());
362 fn.setNumLine(con.getNumLine());
364 //handle wrapper fields
365 ClassDescriptor cd=td.getClassDesc();
366 for(Iterator fieldit=cd.getFields(); fieldit.hasNext(); ) {
367 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
368 if (fd.getType().iswrapper()) {
369 TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType());
370 FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal());
371 fnwrapper.setNumLine(con.getNumLine());
372 FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp);
373 fsfn.setNumLine(con.getNumLine());
374 last.addNext(fnwrapper);
375 fnwrapper.addNext(fsfn);
380 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
383 for(int i=0; i<con.numArgs(); i++) {
384 ExpressionNode en=con.getArg(i);
385 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
387 NodePair np=flattenExpressionNode(en, tmp);
388 last.addNext(np.getBegin());
391 MethodDescriptor md=con.getConstructor();
392 //Call to constructor
393 FlatCall fc=new FlatCall(md, null, out_temp, temps);
394 fc.setNumLine(con.getNumLine());
397 if (td.getClassDesc().hasFlags()) {
398 // if (con.getFlagEffects()!=null) {
399 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
400 ffan.setNumLine(con.getNumLine());
401 FlagEffects fes=con.getFlagEffects();
402 TempDescriptor flagtemp=out_temp;
404 for(int j=0; j<fes.numEffects(); j++) {
405 FlagEffect fe=fes.getEffect(j);
406 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
408 for(int j=0; j<fes.numTagEffects(); j++) {
409 TagEffect te=fes.getTagEffect(j);
410 TempDescriptor tagtemp=getTempforVar(te.getTag());
412 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
415 ffan.addFlagAction(flagtemp, null, false);
420 return new NodePair(fn,last);
422 if(con.getArrayInitializer() == null) {
425 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
426 for (int i=0; i<con.numArgs(); i++) {
427 ExpressionNode en=con.getArg(i);
428 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
430 NodePair np=flattenExpressionNode(en, tmp);
434 last.addNext(np.getBegin());
437 TempDescriptor tmp2=(i==0)?
439 TempDescriptor.tempFactory("arg",en.getType());
441 FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal(), con.getDisjointId());
442 fn.setNumLine(con.getNumLine());
444 if (temps.length>1) {
445 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
446 fn.addNext(np.getBegin());
447 return new NodePair(first,np.getEnd());
448 } else if (td.isArray()&&td.dereference().iswrapper()) {
449 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
450 fn.addNext(np.getBegin());
451 return new NodePair(first,np.getEnd());
453 return new NodePair(first, fn);
455 // array creation with initializers
456 return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
461 private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
462 TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
463 TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
464 FlatNop fnop=new FlatNop(); //last node
467 FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
469 FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
471 TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
473 FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
474 FlatCondBranch fcb=new FlatCondBranch(tmpbool);
475 fcb.setTrueProb(State.TRUEPROB);
478 TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
479 FlatNew fn=td.iswrapper()?new FlatNew(td, new_tmp, isglobal):new FlatNew(td, new_tmp, temparray[i+1], isglobal);
480 FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
482 FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
488 fcb.addFalseNext(fnop);
490 //Recursive call here
491 if ((i+2)<temparray.length) {
492 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
493 fsen.addNext(np2.getBegin());
494 np2.getEnd().addNext(fon);
495 } else if (td.isArray()&&td.dereference().iswrapper()) {
496 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
497 fsen.addNext(np2.getBegin());
498 np2.getEnd().addNext(fon);
503 return new NodePair(fln, fnop);
506 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
507 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
510 TempDescriptor thisarg=null;
512 if (min.getExpression()!=null) {
513 TypeDescriptor mtd = min.getExpression().getType();
514 if(mtd.isClass() && mtd.getClassDesc().isEnum()) {
515 mtd = new TypeDescriptor(TypeDescriptor.INT);
517 thisarg=TempDescriptor.tempFactory("thisarg", mtd);
518 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
524 for(int i=0; i<min.numArgs(); i++) {
525 ExpressionNode en=min.getArg(i);
526 TypeDescriptor etd = en.getType();
527 if(etd.isClass() && etd.getClassDesc().isEnum()) {
528 etd = new TypeDescriptor(TypeDescriptor.INT);
530 TempDescriptor td=TempDescriptor.tempFactory("arg", etd);
532 NodePair np=flattenExpressionNode(en, td);
536 last.addNext(np.getBegin());
540 MethodDescriptor md=min.getMethod();
542 //Call to constructor
545 if(md.getReturnType()==null||md.getReturnType().isVoid())
546 fc=new FlatCall(md, null, thisarg, temps, min.getSuper());
548 fc=new FlatCall(md, out_temp, thisarg, temps, min.getSuper());
550 fc.setNumLine(min.getNumLine());
556 return new NodePair(first,fc);
559 private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
560 TempDescriptor tmp=null;
561 if(fan.getExpression().getType().isClassNameRef()) {
562 // static field dereference with class name
563 tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType());
564 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
565 fn.setNumLine(fan.getNumLine());
566 return new NodePair(fn,fn);
568 tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
569 NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
570 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
571 fn.setNumLine(fan.getNumLine());
572 npe.getEnd().addNext(fn);
573 return new NodePair(npe.getBegin(),fn);
577 private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
578 TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
579 TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
580 NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
581 NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
582 TempDescriptor arraytmp=out_temp;
583 if (aan.iswrapper()) {
585 arraytmp=TempDescriptor.tempFactory("temp", aan.getExpression().getType().dereference());
587 FlatNode fn=new FlatElementNode(tmp,tmpindex,arraytmp);
588 fn.setNumLine(aan.getNumLine());
589 npe.getEnd().addNext(npi.getBegin());
590 npi.getEnd().addNext(fn);
591 if (aan.iswrapper()) {
592 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)aan.getExpression().getType().dereference().getClassDesc().getFieldTable().get("value"),arraytmp,out_temp);
593 ffn.setNumLine(aan.getNumLine());
597 return new NodePair(npe.getBegin(),fn);
600 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
602 // left side is variable
603 // left side is field
604 // left side is array
606 Operation base=an.getOperation().getBaseOp();
607 boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC);
610 //rewrite the base operation
611 base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB);
615 TempDescriptor src_tmp = src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType());
618 if (an.getSrc()!=null) {
619 if(an.getSrc().getEval() != null) {
620 FlatLiteralNode fln=new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
621 fln.setNumLine(an.getSrc().getNumLine());
624 NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
625 first=np_src.getBegin();
626 last=np_src.getEnd();
629 FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
630 fln.setNumLine(an.getNumLine());
635 if (an.getDest().kind()==Kind.FieldAccessNode) {
636 //We are assigning an object field
638 FieldAccessNode fan=(FieldAccessNode)an.getDest();
639 ExpressionNode en=fan.getExpression();
640 TempDescriptor dst_tmp=null;
641 NodePair np_baseexp=null;
642 if(en.getType().isClassNameRef()) {
643 // static field dereference with class name
644 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
645 FlatNop nop=new FlatNop();
646 np_baseexp = new NodePair(nop,nop);
648 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
649 np_baseexp=flattenExpressionNode(en, dst_tmp);
652 first=np_baseexp.getBegin();
654 last.addNext(np_baseexp.getBegin());
655 last=np_baseexp.getEnd();
657 //See if we need to perform an operation
659 //If it is a preinc we need to store the initial value
660 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
661 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
662 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
663 ffn.setNumLine(an.getNumLine());
667 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
668 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
669 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
670 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
671 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
672 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
673 fc1.setNumLine(an.getNumLine());
675 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
676 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
677 fc.setNumLine(an.getNumLine());
683 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
684 fon.setNumLine(an.getNumLine());
691 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
692 fsfn.setNumLine(en.getNumLine());
693 addMapNode2FlatNodeSet(an,fsfn);
697 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
698 fon2.setNumLine(an.getNumLine());
702 return new NodePair(first, last);
703 } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
704 //We are assigning an array element
706 ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
707 ExpressionNode en=aan.getExpression();
708 ExpressionNode enindex=aan.getIndex();
709 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
710 TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
711 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
712 NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
714 first=np_baseexp.getBegin();
716 last.addNext(np_baseexp.getBegin());
717 np_baseexp.getEnd().addNext(np_indexexp.getBegin());
718 last=np_indexexp.getEnd();
720 //See if we need to perform an operation
722 //If it is a preinc we need to store the initial value
723 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
724 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
726 if (aan.iswrapper()) {
727 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
728 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
729 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
730 fen.setNumLine(aan.getNumLine());
731 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp3,src_tmp2);
732 ffn.setNumLine(aan.getNumLine());
737 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
738 fen.setNumLine(aan.getNumLine());
742 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
743 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
744 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
745 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
746 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
747 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
748 fc1.setNumLine(an.getNumLine());
750 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
751 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
752 fc.setNumLine(an.getNumLine());
759 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
760 fon.setNumLine(an.getNumLine());
767 if (aan.iswrapper()) {
768 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
769 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
770 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
771 fen.setNumLine(aan.getNumLine());
772 FlatSetFieldNode fsfn=new FlatSetFieldNode(src_tmp3,(FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp);
773 fsfn.setNumLine(aan.getExpression().getNumLine());
778 FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
779 fsen.setNumLine(aan.getNumLine());
784 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
785 fon2.setNumLine(an.getNumLine());
789 addMapNode2FlatNodeSet(an,last);
790 return new NodePair(first, last);
791 } else if (an.getDest().kind()==Kind.NameNode) {
792 //We could be assigning a field or variable
793 NameNode nn=(NameNode)an.getDest();
796 if (nn.getExpression()!=null) {
798 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
799 ExpressionNode en=fan.getExpression();
800 TempDescriptor dst_tmp=null;
801 NodePair np_baseexp=null;
802 if(en.getType().isClassNameRef()) {
803 // static field dereference with class name
804 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
805 FlatNop nop=new FlatNop();
806 np_baseexp = new NodePair(nop,nop);
808 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
809 np_baseexp=flattenExpressionNode(en, dst_tmp);
812 first=np_baseexp.getBegin();
814 last.addNext(np_baseexp.getBegin());
815 last=np_baseexp.getEnd();
817 //See if we need to perform an operation
819 //If it is a preinc we need to store the initial value
820 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
821 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
823 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
824 ffn.setNumLine(an.getNumLine());
829 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
830 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
831 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
832 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
833 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
834 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
835 fc1.setNumLine(an.getNumLine());
837 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
838 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
839 fc.setNumLine(an.getNumLine());
845 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
846 fon.setNumLine(an.getNumLine());
854 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
855 fsfn.setNumLine(en.getNumLine());
856 addMapNode2FlatNodeSet(an,fsfn);
860 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
861 fon2.setNumLine(an.getNumLine());
865 return new NodePair(first, last);
867 if (nn.getField()!=null) {
871 //See if we need to perform an operation
873 //If it is a preinc we need to store the initial value
874 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
875 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
877 TempDescriptor ftmp= null;
878 if((nn.getClassDesc() != null)) {
879 // this is a static field
880 ftmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
883 ftmp=getTempforVar(nn.getVar());
885 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), ftmp, src_tmp2);
886 ffn.setNumLine(an.getNumLine());
896 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
897 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
898 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
899 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
900 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
901 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
902 fc1.setNumLine(an.getNumLine());
904 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
905 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
906 fc.setNumLine(an.getNumLine());
912 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
913 fon.setNumLine(an.getNumLine());
920 FlatSetFieldNode fsfn=null;
921 if(nn.getClassDesc()!=null) {
922 // this is a static field access inside of a static block
923 fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
924 fsfn.setNumLine(nn.getNumLine());
926 fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
927 fsfn.setNumLine(nn.getNumLine());
929 addMapNode2FlatNodeSet(an,fsfn);
937 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
938 fon2.setNumLine(an.getNumLine());
942 return new NodePair(first, last);
945 //See if we need to perform an operation
948 //If it is a preinc we need to store the initial value
949 TempDescriptor src_tmp2=getTempforVar(nn.getVar());
950 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
952 FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
953 fon.setNumLine(an.getNumLine());
962 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
963 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
964 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
965 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
966 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
967 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
968 fc1.setNumLine(an.getNumLine());
970 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
971 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
972 fc.setNumLine(an.getNumLine());
983 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
984 fon.setNumLine(an.getNumLine());
994 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
995 fon.setNumLine(an.getNumLine());
996 addMapNode2FlatNodeSet(an,fon);
1001 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
1002 fon2.setNumLine(an.getNumLine());
1006 return new NodePair(first, last);
1014 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
1015 if (nn.getExpression()!=null) {
1016 /* Hack - use subtree instead */
1017 return flattenExpressionNode(nn.getExpression(),out_temp);
1018 } else if (nn.getField()!=null) {
1019 TempDescriptor tmp= null;
1020 if((nn.getClassDesc() != null)) {
1021 // this is a static field
1022 tmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
1025 tmp=getTempforVar(nn.getVar());
1027 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
1028 ffn.setNumLine(nn.getNumLine());
1029 addMapNode2FlatNodeSet(nn,ffn);
1030 return new NodePair(ffn,ffn);
1032 TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
1035 out_temp.setTag(tmp.getTag());
1037 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
1038 fon.setNumLine(nn.getNumLine());
1039 addMapNode2FlatNodeSet(nn,fon);
1040 return new NodePair(fon,fon);
1044 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
1045 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
1046 TempDescriptor temp_right=null;
1048 Operation op=on.getOp();
1050 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
1052 if (on.getRight()!=null) {
1053 temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
1054 right=flattenExpressionNode(on.getRight(),temp_right);
1056 FlatNop nop=new FlatNop();
1057 right=new NodePair(nop,nop);
1060 if (op.getOp()==Operation.LOGIC_OR) {
1061 /* Need to do shortcircuiting */
1062 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1063 fcb.setNumLine(on.getNumLine());
1064 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1065 fon1.setNumLine(on.getNumLine());
1066 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1067 fon2.setNumLine(on.getNumLine());
1068 FlatNop fnop=new FlatNop();
1069 left.getEnd().addNext(fcb);
1070 fcb.addFalseNext(right.getBegin());
1071 right.getEnd().addNext(fon2);
1073 fcb.addTrueNext(fon1);
1075 return new NodePair(left.getBegin(), fnop);
1076 } else if (op.getOp()==Operation.LOGIC_AND) {
1077 /* Need to do shortcircuiting */
1078 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1079 fcb.setNumLine(on.getNumLine());
1080 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1081 fon1.setNumLine(on.getNumLine());
1082 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1083 fon2.setNumLine(on.getNumLine());
1084 FlatNop fnop=new FlatNop();
1085 left.getEnd().addNext(fcb);
1086 fcb.addTrueNext(right.getBegin());
1087 right.getEnd().addNext(fon2);
1089 fcb.addFalseNext(fon1);
1091 return new NodePair(left.getBegin(), fnop);
1092 } else if (op.getOp()==Operation.ADD&&on.getLeft().getType().isString()) {
1093 //We have a string concatenate
1094 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
1095 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
1096 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
1097 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
1098 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {temp_left});
1099 fc1.setNumLine(on.getNumLine());
1101 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
1102 FlatCall fc=new FlatCall(concatmd, out_temp, src_tmp3, new TempDescriptor[] {temp_right});
1103 fc.setNumLine(on.getNumLine());
1104 left.getEnd().addNext(right.getBegin());
1105 right.getEnd().addNext(fc1);
1107 return new NodePair(left.getBegin(), fc);
1110 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
1111 fon.setNumLine(on.getNumLine());
1112 left.getEnd().addNext(right.getBegin());
1113 right.getEnd().addNext(fon);
1114 return new NodePair(left.getBegin(),fon);
1117 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
1119 case Kind.AssignmentNode:
1120 return flattenAssignmentNode((AssignmentNode)en,out_temp);
1123 return flattenCastNode((CastNode)en,out_temp);
1125 case Kind.CreateObjectNode:
1126 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
1128 case Kind.FieldAccessNode:
1129 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
1131 case Kind.ArrayAccessNode:
1132 return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
1134 case Kind.LiteralNode:
1135 return flattenLiteralNode((LiteralNode)en,out_temp);
1137 case Kind.MethodInvokeNode:
1138 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
1141 return flattenNameNode((NameNode)en,out_temp);
1144 return flattenOpNode((OpNode)en,out_temp);
1146 case Kind.OffsetNode:
1147 return flattenOffsetNode((OffsetNode)en,out_temp);
1149 case Kind.TertiaryNode:
1150 return flattenTertiaryNode((TertiaryNode)en,out_temp);
1152 case Kind.InstanceOfNode:
1153 return flattenInstanceOfNode((InstanceOfNode)en,out_temp);
1155 case Kind.ArrayInitializerNode:
1156 return flattenArrayInitializerNode((ArrayInitializerNode)en,out_temp);
1161 private NodePair flattenDeclarationNode(DeclarationNode dn) {
1162 VarDescriptor vd=dn.getVarDescriptor();
1163 TempDescriptor td=getTempforVar(vd);
1164 if (dn.getExpression()!=null)
1165 return flattenExpressionNode(dn.getExpression(),td);
1167 FlatNop fn=new FlatNop();
1168 return new NodePair(fn,fn);
1172 private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
1173 TagVarDescriptor tvd=dn.getTagVarDescriptor();
1174 TagDescriptor tag=tvd.getTag();
1175 TempDescriptor tmp=getTempforVar(tvd);
1176 FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
1177 ftd.setNumLine(dn.getNumLine());
1178 return new NodePair(ftd,ftd);
1181 private TempDescriptor getTempforParam(Descriptor d) {
1182 if (temptovar.containsKey(d))
1183 return (TempDescriptor)temptovar.get(d);
1185 if (d instanceof VarDescriptor) {
1186 VarDescriptor vd=(VarDescriptor)d;
1187 TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
1188 temptovar.put(vd,td);
1190 } else if (d instanceof TagVarDescriptor) {
1191 TagVarDescriptor tvd=(TagVarDescriptor)d;
1192 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1193 TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
1194 temptovar.put(tvd,td);
1196 } else throw new Error("Unreconized Descriptor");
1200 private TempDescriptor getTempforVar(Descriptor d) {
1201 if (temptovar.containsKey(d))
1202 return (TempDescriptor)temptovar.get(d);
1204 if (d instanceof VarDescriptor) {
1205 VarDescriptor vd=(VarDescriptor)d;
1206 TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
1207 temptovar.put(vd,td);
1209 } else if (d instanceof TagVarDescriptor) {
1210 TagVarDescriptor tvd=(TagVarDescriptor)d;
1211 //BUGFIX TAGTYPE - add next line, modify following
1212 //line to tag this new type descriptor, modify
1213 //TempDescriptor constructor & factory to set type
1214 //using this Type To test, use any program with tags
1215 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1216 TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
1217 temptovar.put(tvd,td);
1219 } else throw new Error("Unrecognized Descriptor");
1223 private NodePair flattenIfStatementNode(IfStatementNode isn) {
1224 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1225 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
1226 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1227 fcb.setNumLine(isn.getNumLine());
1228 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
1230 FlatNop nopend=new FlatNop();
1232 if (isn.getFalseBlock()!=null)
1233 false_np=flattenBlockNode(isn.getFalseBlock());
1235 FlatNop nop=new FlatNop();
1236 false_np=new NodePair(nop,nop);
1239 cond.getEnd().addNext(fcb);
1240 fcb.addTrueNext(true_np.getBegin());
1241 fcb.addFalseNext(false_np.getBegin());
1242 if (true_np.getEnd()!=null)
1243 true_np.getEnd().addNext(nopend);
1244 if (false_np.getEnd()!=null)
1245 false_np.getEnd().addNext(nopend);
1246 if (nopend.numPrev()==0)
1247 return new NodePair(cond.getBegin(), null);
1249 return new NodePair(cond.getBegin(), nopend);
1252 private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
1253 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
1254 NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
1255 NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp);
1257 cond.getEnd().addNext(sbody.getBegin());
1259 return new NodePair(cond.getBegin(), sbody.getEnd());
1262 private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp) {
1263 FlatNode begin=null;
1265 NodePair prev_true_branch = null;
1266 NodePair prev_false_branch = null;
1267 for(int i=0; i<bn.size(); i++) {
1268 SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
1269 HashSet oldbs=breakset;
1270 breakset=new HashSet();
1272 NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
1273 Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
1274 FlatNode cond_begin = null;
1275 NodePair prev_fnp = null;
1276 for(int j = 0; j < slnv.size(); j++) {
1277 SwitchLabelNode sln = slnv.elementAt(j);
1278 NodePair left = null;
1279 NodePair false_np = null;
1280 if(sln.isDefault()) {
1283 TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1284 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
1285 Operation op=new Operation(Operation.EQUAL);
1286 left=flattenExpressionNode(sln.getCondition(), temp_left);
1287 FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
1288 fon.setNumLine(sln.getNumLine());
1289 left.getEnd().addNext(fon);
1291 FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
1292 fcb.setNumLine(bn.getNumLine());
1293 fcb.setTrueProb(State.TRUEPROB);
1295 FlatNop nop=new FlatNop();
1296 false_np=new NodePair(nop,nop);
1299 fcb.addTrueNext(body.getBegin());
1300 fcb.addFalseNext(false_np.getBegin());
1302 if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
1303 prev_fnp.getEnd().addNext(left.getBegin());
1305 prev_fnp = false_np;
1308 begin = left.getBegin();
1310 if(cond_begin == null) {
1311 cond_begin = left.getBegin();
1314 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1315 prev_false_branch.getEnd().addNext(cond_begin);
1317 prev_false_branch = prev_fnp;
1318 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1319 prev_true_branch.getEnd().addNext(body.getBegin());
1321 prev_true_branch = body;
1322 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1323 FlatNode fn=(FlatNode)breakit.next();
1331 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1334 prev_true_branch.getEnd().addNext(end);
1336 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1339 prev_false_branch.getEnd().addNext(end);
1342 end=begin=new FlatNop();
1344 return new NodePair(begin,end);
1347 private NodePair flattenLoopNode(LoopNode ln) {
1349 HashSet oldbs=breakset;
1350 HashSet oldcs=continueset;
1351 breakset=new HashSet();
1352 continueset=new HashSet();
1354 if (ln.getType()==LoopNode.FORLOOP) {
1355 NodePair initializer=flattenBlockNode(ln.getInitializer());
1356 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1357 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1358 NodePair update=flattenBlockNode(ln.getUpdate());
1359 NodePair body=flattenBlockNode(ln.getBody());
1360 FlatNode begin=initializer.getBegin();
1361 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1362 fcb.setNumLine(ln.getNumLine());
1363 fcb.setTrueProb(State.TRUEPROB);
1365 fcb.setLoopEntrance(condition.getBegin());
1366 FlatNop nopend=new FlatNop();
1367 FlatBackEdge backedge=new FlatBackEdge();
1369 FlatNop nop2=new FlatNop();
1370 initializer.getEnd().addNext(nop2);
1371 nop2.addNext(condition.getBegin());
1372 if (body.getEnd()!=null)
1373 body.getEnd().addNext(update.getBegin());
1374 update.getEnd().addNext(backedge);
1375 backedge.addNext(condition.getBegin());
1376 condition.getEnd().addNext(fcb);
1377 fcb.addFalseNext(nopend);
1378 fcb.addTrueNext(body.getBegin());
1379 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1380 FlatNode fn=(FlatNode)contit.next();
1382 fn.addNext(update.getBegin());
1384 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1385 FlatNode fn=(FlatNode)breakit.next();
1391 if(ln.getLabel()!=null){
1392 state.fn2labelMap.put(condition.getBegin(), ln.getLabel());
1394 return new NodePair(begin,nopend);
1395 } else if (ln.getType()==LoopNode.WHILELOOP) {
1396 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1397 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1398 NodePair body=flattenBlockNode(ln.getBody());
1399 FlatNode begin=condition.getBegin();
1400 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1401 fcb.setNumLine(ln.getNumLine());
1402 fcb.setTrueProb(State.TRUEPROB);
1404 fcb.setLoopEntrance(begin);
1405 FlatNop nopend=new FlatNop();
1406 FlatBackEdge backedge=new FlatBackEdge();
1408 if (body.getEnd()!=null)
1409 body.getEnd().addNext(backedge);
1410 backedge.addNext(condition.getBegin());
1412 condition.getEnd().addNext(fcb);
1413 fcb.addFalseNext(nopend);
1414 fcb.addTrueNext(body.getBegin());
1416 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1417 FlatNode fn=(FlatNode)contit.next();
1419 fn.addNext(backedge);
1421 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1422 FlatNode fn=(FlatNode)breakit.next();
1428 if(ln.getLabel()!=null){
1429 state.fn2labelMap.put(begin, ln.getLabel());
1431 return new NodePair(begin,nopend);
1432 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
1433 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1434 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1435 NodePair body=flattenBlockNode(ln.getBody());
1436 FlatNode begin=body.getBegin();
1437 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1438 fcb.setNumLine(ln.getNumLine());
1439 fcb.setTrueProb(State.TRUEPROB);
1441 fcb.setLoopEntrance(begin);
1442 FlatNop nopend=new FlatNop();
1443 FlatBackEdge backedge=new FlatBackEdge();
1445 if (body.getEnd()!=null)
1446 body.getEnd().addNext(condition.getBegin());
1447 condition.getEnd().addNext(fcb);
1448 fcb.addFalseNext(nopend);
1449 fcb.addTrueNext(backedge);
1450 backedge.addNext(body.getBegin());
1452 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1453 FlatNode fn=(FlatNode)contit.next();
1455 fn.addNext(condition.getBegin());
1457 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1458 FlatNode fn=(FlatNode)breakit.next();
1464 if(ln.getLabel()!=null){
1465 state.fn2labelMap.put(begin, ln.getLabel());
1467 return new NodePair(begin,nopend);
1468 } else throw new Error();
1471 private NodePair flattenReturnNode(ReturnNode rntree) {
1472 TempDescriptor retval=null;
1474 if (rntree.getReturnExpression()!=null) {
1475 retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
1476 cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
1479 FlatReturnNode rnflat=new FlatReturnNode(retval);
1480 rnflat.setNumLine(rntree.getNumLine());
1483 if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
1485 //XXXXXXXXX: FIX THIS
1487 FlatNode end = null;
1488 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1489 for(int j = this.lockStack.size(); j > 0; j--) {
1490 TempDescriptor thistd = this.lockStack.elementAt(j-1);
1491 FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
1492 fcunlock.setNumLine(rntree.getNumLine());
1494 end.addNext(fcunlock);
1502 if (state.DSM&&currmd.getModifiers().isAtomic()) {
1503 FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
1509 cond.getEnd().addNext(ln);
1510 return new NodePair(cond.getBegin(),null);
1512 return new NodePair(ln,null);
1515 private NodePair flattenTaskExitNode(TaskExitNode ten) {
1516 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
1517 ffan.setTaskExitIndex(ten.getTaskExitIndex());
1518 updateFlagActionNode(ffan, ten.getFlagEffects());
1519 NodePair fcn=flattenConstraintCheck(ten.getChecks());
1520 ffan.addNext(fcn.getBegin());
1521 FlatReturnNode rnflat=new FlatReturnNode(null);
1522 rnflat.setNumLine(ten.getNumLine());
1524 fcn.getEnd().addNext(rnflat);
1525 return new NodePair(ffan, null);
1528 private NodePair flattenConstraintCheck(Vector ccs) {
1529 FlatNode begin=new FlatNop();
1531 return new NodePair(begin,begin);
1532 FlatNode last=begin;
1533 for(int i=0; i<ccs.size(); i++) {
1534 ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
1535 /* Flatten the arguments */
1536 TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
1537 String[] vars=new String[cc.numArgs()];
1538 for(int j=0; j<cc.numArgs(); j++) {
1539 ExpressionNode en=cc.getArg(j);
1540 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
1542 vars[j]=cc.getVar(j);
1543 NodePair np=flattenExpressionNode(en, td);
1544 last.addNext(np.getBegin());
1548 FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
1552 return new NodePair(begin,last);
1555 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
1556 return flattenBlockNode(sbn.getBlockNode());
1559 private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
1560 TempDescriptor montmp=null;
1561 FlatNode first = null;
1562 FlatNode end = null;
1563 if(sbn.getExpr() instanceof ClassTypeNode) {
1564 montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
1566 montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
1567 NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
1568 first = npexp.getBegin();
1569 end = npexp.getEnd();
1571 this.lockStack.push(montmp);
1572 NodePair npblock=flattenBlockNode(sbn.getBlockNode());
1574 this.lockStack.pop();
1577 MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
1578 FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
1579 fcen.setNumLine(sbn.getNumLine());
1581 MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1582 FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
1583 fcex.setNumLine(sbn.getNumLine());
1585 this.lockStack.pop();
1592 fcen.addNext(npblock.getBegin());
1594 if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
1595 npblock.getEnd().addNext(fcex);
1596 return new NodePair(first, fcex);
1598 return new NodePair(first, null);
1603 private NodePair flattenAtomicNode(AtomicNode sbn) {
1604 NodePair np=flattenBlockNode(sbn.getBlockNode());
1605 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
1606 faen.setNumLine(sbn.getNumLine());
1607 FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
1608 faen.addNext(np.getBegin());
1609 np.getEnd().addNext(faexn);
1610 return new NodePair(faen, faexn);
1613 private NodePair flattenGenReachNode(GenReachNode grn) {
1614 FlatGenReachNode fgrn = new FlatGenReachNode(grn.getGraphName() );
1615 return new NodePair(fgrn, fgrn);
1618 private NodePair flattenGenDefReachNode(GenDefReachNode gdrn) {
1619 FlatGenDefReachNode fgdrn = new FlatGenDefReachNode(gdrn.getOutputName() );
1620 return new NodePair(fgdrn, fgdrn);
1623 private NodePair flattenSESENode(SESENode sn) {
1624 if( sn.isStart() ) {
1625 FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
1626 fsen.setNumLine(sn.getNumLine());
1627 sn.setFlatEnter(fsen);
1628 return new NodePair(fsen, fsen);
1631 FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
1632 sn.setFlatExit(fsexn);
1633 FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
1634 fsexn.setFlatEnter(fsen);
1635 sn.getStart().getFlatEnter().setFlatExit(fsexn);
1637 return new NodePair(fsexn, fsexn);
1640 private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
1641 FlatNop fn=new FlatNop();
1645 continueset.add(fn);
1646 return new NodePair(fn,null);
1649 private NodePair flattenInstanceOfNode(InstanceOfNode tn, TempDescriptor out_temp) {
1650 TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
1651 NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
1652 FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
1653 fion.setNumLine(tn.getNumLine());
1654 cond.getEnd().addNext(fion);
1655 return new NodePair(cond.getBegin(),fion);
1658 private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
1659 boolean isGlobal = false;
1660 String disjointId = null;
1661 // get the type the array to be initialized
1662 TypeDescriptor td = ain.getType();
1664 // create a new array of size equal to the array initializer
1665 FlatNode first=null;
1667 TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
1668 FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
1669 fln_tmp.setNumLine(ain.getNumLine());
1670 first = last=fln_tmp;
1672 // create the new array
1673 FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
1674 fn.setNumLine(ain.getNumLine());
1678 // initialize the new array
1679 for(int i = 0; i < ain.numVarInitializers(); i++) {
1680 ExpressionNode var_init_node = ain.getVarInitializer(i);
1681 TempDescriptor tmp_toinit = out_temp;
1682 TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
1684 TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
1685 FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
1686 fln.setNumLine(ain.getNumLine());
1687 // calculate the initial value
1688 NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
1689 // TODO wrapper class process is missing now
1690 /*if(td.isArray() && td.dereference().iswrapper()) {
1692 FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
1693 fsen.setNumLine(ain.getNumLine());
1695 fln.addNext(np_init.getBegin());
1696 np_init.getEnd().addNext(fsen);
1700 return new NodePair(first, last);
1703 private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
1704 TempDescriptor cond_temp=TempDescriptor.tempFactory("tert_cond",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1705 TempDescriptor true_temp=TempDescriptor.tempFactory("tert_true",tn.getTrueExpr().getType());
1706 TempDescriptor fals_temp=TempDescriptor.tempFactory("tert_fals",tn.getFalseExpr().getType());
1708 NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
1709 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1710 fcb.setNumLine(tn.getNumLine());
1712 NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
1713 FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
1714 fonT.setNumLine(tn.getNumLine());
1716 NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
1717 FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
1718 fonF.setNumLine(tn.getNumLine());
1720 FlatNop nopend=new FlatNop();
1722 cond.getEnd().addNext(fcb);
1724 fcb.addTrueNext(trueExpr.getBegin());
1725 fcb.addFalseNext(falseExpr.getBegin());
1727 trueExpr.getEnd().addNext(fonT);
1728 fonT.addNext(nopend);
1730 falseExpr.getEnd().addNext(fonF);
1731 fonF.addNext(nopend);
1733 return new NodePair(cond.getBegin(), nopend);
1736 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
1737 switch(bsn.kind()) {
1738 case Kind.BlockExpressionNode:
1739 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
1741 case Kind.DeclarationNode:
1742 return flattenDeclarationNode((DeclarationNode)bsn);
1744 case Kind.TagDeclarationNode:
1745 return flattenTagDeclarationNode((TagDeclarationNode)bsn);
1747 case Kind.IfStatementNode:
1748 return flattenIfStatementNode((IfStatementNode)bsn);
1750 case Kind.SwitchStatementNode:
1751 return flattenSwitchStatementNode((SwitchStatementNode)bsn);
1754 return flattenLoopNode((LoopNode)bsn);
1756 case Kind.ReturnNode:
1757 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
1759 case Kind.TaskExitNode:
1760 return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
1762 case Kind.SubBlockNode:
1763 return flattenSubBlockNode((SubBlockNode)bsn);
1765 case Kind.AtomicNode:
1766 return flattenAtomicNode((AtomicNode)bsn);
1768 case Kind.SynchronizedNode:
1769 return flattenSynchronizedNode((SynchronizedNode)bsn);
1772 return flattenSESENode((SESENode)bsn);
1774 case Kind.GenReachNode:
1775 return flattenGenReachNode((GenReachNode)bsn);
1777 case Kind.GenDefReachNode:
1778 return flattenGenDefReachNode((GenDefReachNode)bsn);
1780 case Kind.ContinueBreakNode:
1781 return flattenContinueBreakNode((ContinueBreakNode)bsn);
1786 private void addMapNode2FlatNodeSet(TreeNode tn, FlatNode fn){
1787 Set<FlatNode> fnSet=mapNode2FlatNodeSet.get(tn);
1789 fnSet=new HashSet<FlatNode>();
1790 mapNode2FlatNodeSet.put(tn, fnSet);
1795 public Set<FlatNode> getFlatNodeSet(TreeNode tn){
1796 // WARNING: ONLY DID FOR NAMENODE NOW!
1797 assert(tn instanceof NameNode);
1798 return mapNode2FlatNodeSet.get(tn);