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());
694 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
695 fon2.setNumLine(an.getNumLine());
699 return new NodePair(first, last);
700 } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
701 //We are assigning an array element
703 ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
704 ExpressionNode en=aan.getExpression();
705 ExpressionNode enindex=aan.getIndex();
706 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
707 TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
708 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
709 NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
711 first=np_baseexp.getBegin();
713 last.addNext(np_baseexp.getBegin());
714 np_baseexp.getEnd().addNext(np_indexexp.getBegin());
715 last=np_indexexp.getEnd();
717 //See if we need to perform an operation
719 //If it is a preinc we need to store the initial value
720 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
721 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
723 if (aan.iswrapper()) {
724 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
725 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
726 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
727 fen.setNumLine(aan.getNumLine());
728 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp3,src_tmp2);
729 ffn.setNumLine(aan.getNumLine());
734 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
735 fen.setNumLine(aan.getNumLine());
739 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
740 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
741 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
742 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
743 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
744 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
745 fc1.setNumLine(an.getNumLine());
747 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
748 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
749 fc.setNumLine(an.getNumLine());
756 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
757 fon.setNumLine(an.getNumLine());
764 if (aan.iswrapper()) {
765 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
766 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
767 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
768 fen.setNumLine(aan.getNumLine());
769 FlatSetFieldNode fsfn=new FlatSetFieldNode(src_tmp3,(FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp);
770 fsfn.setNumLine(aan.getExpression().getNumLine());
775 FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
776 fsen.setNumLine(aan.getNumLine());
781 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
782 fon2.setNumLine(an.getNumLine());
786 return new NodePair(first, last);
787 } else if (an.getDest().kind()==Kind.NameNode) {
788 //We could be assigning a field or variable
789 NameNode nn=(NameNode)an.getDest();
792 if (nn.getExpression()!=null) {
794 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
795 ExpressionNode en=fan.getExpression();
796 TempDescriptor dst_tmp=null;
797 NodePair np_baseexp=null;
798 if(en.getType().isClassNameRef()) {
799 // static field dereference with class name
800 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
801 FlatNop nop=new FlatNop();
802 np_baseexp = new NodePair(nop,nop);
804 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
805 np_baseexp=flattenExpressionNode(en, dst_tmp);
808 first=np_baseexp.getBegin();
810 last.addNext(np_baseexp.getBegin());
811 last=np_baseexp.getEnd();
813 //See if we need to perform an operation
815 //If it is a preinc we need to store the initial value
816 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
817 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
819 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
820 ffn.setNumLine(an.getNumLine());
825 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
826 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
827 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
828 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
829 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
830 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
831 fc1.setNumLine(an.getNumLine());
833 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
834 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
835 fc.setNumLine(an.getNumLine());
841 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
842 fon.setNumLine(an.getNumLine());
850 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
851 fsfn.setNumLine(en.getNumLine());
855 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
856 fon2.setNumLine(an.getNumLine());
860 return new NodePair(first, last);
862 if (nn.getField()!=null) {
866 //See if we need to perform an operation
868 //If it is a preinc we need to store the initial value
869 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
870 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
872 TempDescriptor ftmp= null;
873 if((nn.getClassDesc() != null)) {
874 // this is a static field
875 ftmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
878 ftmp=getTempforVar(nn.getVar());
880 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), ftmp, src_tmp2);
881 ffn.setNumLine(an.getNumLine());
891 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
892 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
893 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
894 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
895 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
896 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
897 fc1.setNumLine(an.getNumLine());
899 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
900 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
901 fc.setNumLine(an.getNumLine());
907 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
908 fon.setNumLine(an.getNumLine());
915 FlatSetFieldNode fsfn=null;
916 if(nn.getClassDesc()!=null) {
917 // this is a static field access inside of a static block
918 fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
919 fsfn.setNumLine(nn.getNumLine());
921 fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
922 fsfn.setNumLine(nn.getNumLine());
931 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
932 fon2.setNumLine(an.getNumLine());
936 return new NodePair(first, last);
939 //See if we need to perform an operation
942 //If it is a preinc we need to store the initial value
943 TempDescriptor src_tmp2=getTempforVar(nn.getVar());
944 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
946 FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
947 fon.setNumLine(an.getNumLine());
956 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
957 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
958 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
959 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
960 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
961 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
962 fc1.setNumLine(an.getNumLine());
964 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
965 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
966 fc.setNumLine(an.getNumLine());
977 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
978 fon.setNumLine(an.getNumLine());
988 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
989 fon.setNumLine(an.getNumLine());
994 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
995 fon2.setNumLine(an.getNumLine());
999 return new NodePair(first, last);
1007 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
1008 if (nn.getExpression()!=null) {
1009 /* Hack - use subtree instead */
1010 return flattenExpressionNode(nn.getExpression(),out_temp);
1011 } else if (nn.getField()!=null) {
1012 TempDescriptor tmp= null;
1013 if((nn.getClassDesc() != null)) {
1014 // this is a static field
1015 tmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
1018 tmp=getTempforVar(nn.getVar());
1020 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
1021 ffn.setNumLine(nn.getNumLine());
1022 addMapNode2FlatNodeSet(nn,ffn);
1023 return new NodePair(ffn,ffn);
1025 TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
1028 out_temp.setTag(tmp.getTag());
1030 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
1031 fon.setNumLine(nn.getNumLine());
1032 addMapNode2FlatNodeSet(nn,fon);
1033 return new NodePair(fon,fon);
1037 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
1038 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
1039 TempDescriptor temp_right=null;
1041 Operation op=on.getOp();
1043 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
1045 if (on.getRight()!=null) {
1046 temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
1047 right=flattenExpressionNode(on.getRight(),temp_right);
1049 FlatNop nop=new FlatNop();
1050 right=new NodePair(nop,nop);
1053 if (op.getOp()==Operation.LOGIC_OR) {
1054 /* Need to do shortcircuiting */
1055 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1056 fcb.setNumLine(on.getNumLine());
1057 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1058 fon1.setNumLine(on.getNumLine());
1059 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1060 fon2.setNumLine(on.getNumLine());
1061 FlatNop fnop=new FlatNop();
1062 left.getEnd().addNext(fcb);
1063 fcb.addFalseNext(right.getBegin());
1064 right.getEnd().addNext(fon2);
1066 fcb.addTrueNext(fon1);
1068 return new NodePair(left.getBegin(), fnop);
1069 } else if (op.getOp()==Operation.LOGIC_AND) {
1070 /* Need to do shortcircuiting */
1071 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1072 fcb.setNumLine(on.getNumLine());
1073 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1074 fon1.setNumLine(on.getNumLine());
1075 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1076 fon2.setNumLine(on.getNumLine());
1077 FlatNop fnop=new FlatNop();
1078 left.getEnd().addNext(fcb);
1079 fcb.addTrueNext(right.getBegin());
1080 right.getEnd().addNext(fon2);
1082 fcb.addFalseNext(fon1);
1084 return new NodePair(left.getBegin(), fnop);
1085 } else if (op.getOp()==Operation.ADD&&on.getLeft().getType().isString()) {
1086 //We have a string concatenate
1087 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
1088 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
1089 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
1090 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
1091 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {temp_left});
1092 fc1.setNumLine(on.getNumLine());
1094 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
1095 FlatCall fc=new FlatCall(concatmd, out_temp, src_tmp3, new TempDescriptor[] {temp_right});
1096 fc.setNumLine(on.getNumLine());
1097 left.getEnd().addNext(right.getBegin());
1098 right.getEnd().addNext(fc1);
1100 return new NodePair(left.getBegin(), fc);
1103 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
1104 fon.setNumLine(on.getNumLine());
1105 left.getEnd().addNext(right.getBegin());
1106 right.getEnd().addNext(fon);
1107 return new NodePair(left.getBegin(),fon);
1110 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
1112 case Kind.AssignmentNode:
1113 return flattenAssignmentNode((AssignmentNode)en,out_temp);
1116 return flattenCastNode((CastNode)en,out_temp);
1118 case Kind.CreateObjectNode:
1119 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
1121 case Kind.FieldAccessNode:
1122 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
1124 case Kind.ArrayAccessNode:
1125 return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
1127 case Kind.LiteralNode:
1128 return flattenLiteralNode((LiteralNode)en,out_temp);
1130 case Kind.MethodInvokeNode:
1131 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
1134 return flattenNameNode((NameNode)en,out_temp);
1137 return flattenOpNode((OpNode)en,out_temp);
1139 case Kind.OffsetNode:
1140 return flattenOffsetNode((OffsetNode)en,out_temp);
1142 case Kind.TertiaryNode:
1143 return flattenTertiaryNode((TertiaryNode)en,out_temp);
1145 case Kind.InstanceOfNode:
1146 return flattenInstanceOfNode((InstanceOfNode)en,out_temp);
1148 case Kind.ArrayInitializerNode:
1149 return flattenArrayInitializerNode((ArrayInitializerNode)en,out_temp);
1154 private NodePair flattenDeclarationNode(DeclarationNode dn) {
1155 VarDescriptor vd=dn.getVarDescriptor();
1156 TempDescriptor td=getTempforVar(vd);
1157 if (dn.getExpression()!=null)
1158 return flattenExpressionNode(dn.getExpression(),td);
1160 FlatNop fn=new FlatNop();
1161 return new NodePair(fn,fn);
1165 private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
1166 TagVarDescriptor tvd=dn.getTagVarDescriptor();
1167 TagDescriptor tag=tvd.getTag();
1168 TempDescriptor tmp=getTempforVar(tvd);
1169 FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
1170 ftd.setNumLine(dn.getNumLine());
1171 return new NodePair(ftd,ftd);
1174 private TempDescriptor getTempforParam(Descriptor d) {
1175 if (temptovar.containsKey(d))
1176 return (TempDescriptor)temptovar.get(d);
1178 if (d instanceof VarDescriptor) {
1179 VarDescriptor vd=(VarDescriptor)d;
1180 TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
1181 temptovar.put(vd,td);
1183 } else if (d instanceof TagVarDescriptor) {
1184 TagVarDescriptor tvd=(TagVarDescriptor)d;
1185 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1186 TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
1187 temptovar.put(tvd,td);
1189 } else throw new Error("Unreconized Descriptor");
1193 private TempDescriptor getTempforVar(Descriptor d) {
1194 if (temptovar.containsKey(d))
1195 return (TempDescriptor)temptovar.get(d);
1197 if (d instanceof VarDescriptor) {
1198 VarDescriptor vd=(VarDescriptor)d;
1199 TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
1200 temptovar.put(vd,td);
1202 } else if (d instanceof TagVarDescriptor) {
1203 TagVarDescriptor tvd=(TagVarDescriptor)d;
1204 //BUGFIX TAGTYPE - add next line, modify following
1205 //line to tag this new type descriptor, modify
1206 //TempDescriptor constructor & factory to set type
1207 //using this Type To test, use any program with tags
1208 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1209 TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
1210 temptovar.put(tvd,td);
1212 } else throw new Error("Unrecognized Descriptor");
1216 private NodePair flattenIfStatementNode(IfStatementNode isn) {
1217 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1218 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
1219 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1220 fcb.setNumLine(isn.getNumLine());
1221 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
1223 FlatNop nopend=new FlatNop();
1225 if (isn.getFalseBlock()!=null)
1226 false_np=flattenBlockNode(isn.getFalseBlock());
1228 FlatNop nop=new FlatNop();
1229 false_np=new NodePair(nop,nop);
1232 cond.getEnd().addNext(fcb);
1233 fcb.addTrueNext(true_np.getBegin());
1234 fcb.addFalseNext(false_np.getBegin());
1235 if (true_np.getEnd()!=null)
1236 true_np.getEnd().addNext(nopend);
1237 if (false_np.getEnd()!=null)
1238 false_np.getEnd().addNext(nopend);
1239 if (nopend.numPrev()==0)
1240 return new NodePair(cond.getBegin(), null);
1242 return new NodePair(cond.getBegin(), nopend);
1245 private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
1246 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
1247 NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
1248 NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp);
1250 cond.getEnd().addNext(sbody.getBegin());
1252 return new NodePair(cond.getBegin(), sbody.getEnd());
1255 private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp) {
1256 FlatNode begin=null;
1258 NodePair prev_true_branch = null;
1259 NodePair prev_false_branch = null;
1260 for(int i=0; i<bn.size(); i++) {
1261 SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
1262 HashSet oldbs=breakset;
1263 breakset=new HashSet();
1265 NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
1266 Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
1267 FlatNode cond_begin = null;
1268 NodePair prev_fnp = null;
1269 for(int j = 0; j < slnv.size(); j++) {
1270 SwitchLabelNode sln = slnv.elementAt(j);
1271 NodePair left = null;
1272 NodePair false_np = null;
1273 if(sln.isDefault()) {
1276 TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1277 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
1278 Operation op=new Operation(Operation.EQUAL);
1279 left=flattenExpressionNode(sln.getCondition(), temp_left);
1280 FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
1281 fon.setNumLine(sln.getNumLine());
1282 left.getEnd().addNext(fon);
1284 FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
1285 fcb.setNumLine(bn.getNumLine());
1286 fcb.setTrueProb(State.TRUEPROB);
1288 FlatNop nop=new FlatNop();
1289 false_np=new NodePair(nop,nop);
1292 fcb.addTrueNext(body.getBegin());
1293 fcb.addFalseNext(false_np.getBegin());
1295 if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
1296 prev_fnp.getEnd().addNext(left.getBegin());
1298 prev_fnp = false_np;
1301 begin = left.getBegin();
1303 if(cond_begin == null) {
1304 cond_begin = left.getBegin();
1307 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1308 prev_false_branch.getEnd().addNext(cond_begin);
1310 prev_false_branch = prev_fnp;
1311 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1312 prev_true_branch.getEnd().addNext(body.getBegin());
1314 prev_true_branch = body;
1315 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1316 FlatNode fn=(FlatNode)breakit.next();
1324 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1327 prev_true_branch.getEnd().addNext(end);
1329 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1332 prev_false_branch.getEnd().addNext(end);
1335 end=begin=new FlatNop();
1337 return new NodePair(begin,end);
1340 private NodePair flattenLoopNode(LoopNode ln) {
1342 HashSet oldbs=breakset;
1343 HashSet oldcs=continueset;
1344 breakset=new HashSet();
1345 continueset=new HashSet();
1347 if (ln.getType()==LoopNode.FORLOOP) {
1348 NodePair initializer=flattenBlockNode(ln.getInitializer());
1349 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1350 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1351 NodePair update=flattenBlockNode(ln.getUpdate());
1352 NodePair body=flattenBlockNode(ln.getBody());
1353 FlatNode begin=initializer.getBegin();
1354 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1355 fcb.setNumLine(ln.getNumLine());
1356 fcb.setTrueProb(State.TRUEPROB);
1358 fcb.setLoopEntrance(condition.getBegin());
1359 FlatNop nopend=new FlatNop();
1360 FlatBackEdge backedge=new FlatBackEdge();
1362 FlatNop nop2=new FlatNop();
1363 initializer.getEnd().addNext(nop2);
1364 nop2.addNext(condition.getBegin());
1365 if (body.getEnd()!=null)
1366 body.getEnd().addNext(update.getBegin());
1367 update.getEnd().addNext(backedge);
1368 backedge.addNext(condition.getBegin());
1369 condition.getEnd().addNext(fcb);
1370 fcb.addFalseNext(nopend);
1371 fcb.addTrueNext(body.getBegin());
1372 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1373 FlatNode fn=(FlatNode)contit.next();
1375 fn.addNext(update.getBegin());
1377 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1378 FlatNode fn=(FlatNode)breakit.next();
1384 if(ln.getLabel()!=null){
1385 state.fn2labelMap.put(condition.getBegin(), ln.getLabel());
1387 return new NodePair(begin,nopend);
1388 } else if (ln.getType()==LoopNode.WHILELOOP) {
1389 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1390 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1391 NodePair body=flattenBlockNode(ln.getBody());
1392 FlatNode begin=condition.getBegin();
1393 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1394 fcb.setNumLine(ln.getNumLine());
1395 fcb.setTrueProb(State.TRUEPROB);
1397 fcb.setLoopEntrance(begin);
1398 FlatNop nopend=new FlatNop();
1399 FlatBackEdge backedge=new FlatBackEdge();
1401 if (body.getEnd()!=null)
1402 body.getEnd().addNext(backedge);
1403 backedge.addNext(condition.getBegin());
1405 condition.getEnd().addNext(fcb);
1406 fcb.addFalseNext(nopend);
1407 fcb.addTrueNext(body.getBegin());
1409 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1410 FlatNode fn=(FlatNode)contit.next();
1412 fn.addNext(backedge);
1414 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1415 FlatNode fn=(FlatNode)breakit.next();
1421 if(ln.getLabel()!=null){
1422 state.fn2labelMap.put(begin, ln.getLabel());
1424 return new NodePair(begin,nopend);
1425 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
1426 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1427 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1428 NodePair body=flattenBlockNode(ln.getBody());
1429 FlatNode begin=body.getBegin();
1430 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1431 fcb.setNumLine(ln.getNumLine());
1432 fcb.setTrueProb(State.TRUEPROB);
1434 fcb.setLoopEntrance(begin);
1435 FlatNop nopend=new FlatNop();
1436 FlatBackEdge backedge=new FlatBackEdge();
1438 if (body.getEnd()!=null)
1439 body.getEnd().addNext(condition.getBegin());
1440 condition.getEnd().addNext(fcb);
1441 fcb.addFalseNext(nopend);
1442 fcb.addTrueNext(backedge);
1443 backedge.addNext(body.getBegin());
1445 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1446 FlatNode fn=(FlatNode)contit.next();
1448 fn.addNext(condition.getBegin());
1450 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1451 FlatNode fn=(FlatNode)breakit.next();
1457 if(ln.getLabel()!=null){
1458 state.fn2labelMap.put(begin, ln.getLabel());
1460 return new NodePair(begin,nopend);
1461 } else throw new Error();
1464 private NodePair flattenReturnNode(ReturnNode rntree) {
1465 TempDescriptor retval=null;
1467 if (rntree.getReturnExpression()!=null) {
1468 retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
1469 cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
1472 FlatReturnNode rnflat=new FlatReturnNode(retval);
1473 rnflat.setNumLine(rntree.getNumLine());
1476 if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
1478 //XXXXXXXXX: FIX THIS
1480 FlatNode end = null;
1481 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1482 for(int j = this.lockStack.size(); j > 0; j--) {
1483 TempDescriptor thistd = this.lockStack.elementAt(j-1);
1484 FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
1485 fcunlock.setNumLine(rntree.getNumLine());
1487 end.addNext(fcunlock);
1495 if (state.DSM&&currmd.getModifiers().isAtomic()) {
1496 FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
1502 cond.getEnd().addNext(ln);
1503 return new NodePair(cond.getBegin(),null);
1505 return new NodePair(ln,null);
1508 private NodePair flattenTaskExitNode(TaskExitNode ten) {
1509 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
1510 ffan.setTaskExitIndex(ten.getTaskExitIndex());
1511 updateFlagActionNode(ffan, ten.getFlagEffects());
1512 NodePair fcn=flattenConstraintCheck(ten.getChecks());
1513 ffan.addNext(fcn.getBegin());
1514 FlatReturnNode rnflat=new FlatReturnNode(null);
1515 rnflat.setNumLine(ten.getNumLine());
1517 fcn.getEnd().addNext(rnflat);
1518 return new NodePair(ffan, null);
1521 private NodePair flattenConstraintCheck(Vector ccs) {
1522 FlatNode begin=new FlatNop();
1524 return new NodePair(begin,begin);
1525 FlatNode last=begin;
1526 for(int i=0; i<ccs.size(); i++) {
1527 ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
1528 /* Flatten the arguments */
1529 TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
1530 String[] vars=new String[cc.numArgs()];
1531 for(int j=0; j<cc.numArgs(); j++) {
1532 ExpressionNode en=cc.getArg(j);
1533 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
1535 vars[j]=cc.getVar(j);
1536 NodePair np=flattenExpressionNode(en, td);
1537 last.addNext(np.getBegin());
1541 FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
1545 return new NodePair(begin,last);
1548 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
1549 return flattenBlockNode(sbn.getBlockNode());
1552 private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
1553 TempDescriptor montmp=null;
1554 FlatNode first = null;
1555 FlatNode end = null;
1556 if(sbn.getExpr() instanceof ClassTypeNode) {
1557 montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
1559 montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
1560 NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
1561 first = npexp.getBegin();
1562 end = npexp.getEnd();
1564 this.lockStack.push(montmp);
1565 NodePair npblock=flattenBlockNode(sbn.getBlockNode());
1567 this.lockStack.pop();
1570 MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
1571 FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
1572 fcen.setNumLine(sbn.getNumLine());
1574 MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1575 FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
1576 fcex.setNumLine(sbn.getNumLine());
1578 this.lockStack.pop();
1585 fcen.addNext(npblock.getBegin());
1587 if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
1588 npblock.getEnd().addNext(fcex);
1589 return new NodePair(first, fcex);
1591 return new NodePair(first, null);
1596 private NodePair flattenAtomicNode(AtomicNode sbn) {
1597 NodePair np=flattenBlockNode(sbn.getBlockNode());
1598 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
1599 faen.setNumLine(sbn.getNumLine());
1600 FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
1601 faen.addNext(np.getBegin());
1602 np.getEnd().addNext(faexn);
1603 return new NodePair(faen, faexn);
1606 private NodePair flattenGenReachNode(GenReachNode grn) {
1607 FlatGenReachNode fgrn = new FlatGenReachNode(grn.getGraphName() );
1608 return new NodePair(fgrn, fgrn);
1611 private NodePair flattenGenDefReachNode(GenDefReachNode gdrn) {
1612 FlatGenDefReachNode fgdrn = new FlatGenDefReachNode(gdrn.getOutputName() );
1613 return new NodePair(fgdrn, fgdrn);
1616 private NodePair flattenSESENode(SESENode sn) {
1617 if( sn.isStart() ) {
1618 FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
1619 fsen.setNumLine(sn.getNumLine());
1620 sn.setFlatEnter(fsen);
1621 return new NodePair(fsen, fsen);
1624 FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
1625 sn.setFlatExit(fsexn);
1626 FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
1627 fsexn.setFlatEnter(fsen);
1628 sn.getStart().getFlatEnter().setFlatExit(fsexn);
1630 return new NodePair(fsexn, fsexn);
1633 private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
1634 FlatNop fn=new FlatNop();
1638 continueset.add(fn);
1639 return new NodePair(fn,null);
1642 private NodePair flattenInstanceOfNode(InstanceOfNode tn, TempDescriptor out_temp) {
1643 TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
1644 NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
1645 FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
1646 fion.setNumLine(tn.getNumLine());
1647 cond.getEnd().addNext(fion);
1648 return new NodePair(cond.getBegin(),fion);
1651 private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
1652 boolean isGlobal = false;
1653 String disjointId = null;
1654 // get the type the array to be initialized
1655 TypeDescriptor td = ain.getType();
1657 // create a new array of size equal to the array initializer
1658 FlatNode first=null;
1660 TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
1661 FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
1662 fln_tmp.setNumLine(ain.getNumLine());
1663 first = last=fln_tmp;
1665 // create the new array
1666 FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
1670 // initialize the new array
1671 for(int i = 0; i < ain.numVarInitializers(); i++) {
1672 ExpressionNode var_init_node = ain.getVarInitializer(i);
1673 TempDescriptor tmp_toinit = out_temp;
1674 TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
1676 TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
1677 FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
1678 fln.setNumLine(ain.getNumLine());
1679 // calculate the initial value
1680 NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
1681 // TODO wrapper class process is missing now
1682 /*if(td.isArray() && td.dereference().iswrapper()) {
1684 FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
1685 fsen.setNumLine(ain.getNumLine());
1687 fln.addNext(np_init.getBegin());
1688 np_init.getEnd().addNext(fsen);
1692 return new NodePair(first, last);
1695 private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
1696 TempDescriptor cond_temp=TempDescriptor.tempFactory("tert_cond",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1697 TempDescriptor true_temp=TempDescriptor.tempFactory("tert_true",tn.getTrueExpr().getType());
1698 TempDescriptor fals_temp=TempDescriptor.tempFactory("tert_fals",tn.getFalseExpr().getType());
1700 NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
1701 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1702 fcb.setNumLine(tn.getNumLine());
1704 NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
1705 FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
1706 fonT.setNumLine(tn.getNumLine());
1708 NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
1709 FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
1710 fonF.setNumLine(tn.getNumLine());
1712 FlatNop nopend=new FlatNop();
1714 cond.getEnd().addNext(fcb);
1716 fcb.addTrueNext(trueExpr.getBegin());
1717 fcb.addFalseNext(falseExpr.getBegin());
1719 trueExpr.getEnd().addNext(fonT);
1720 fonT.addNext(nopend);
1722 falseExpr.getEnd().addNext(fonF);
1723 fonF.addNext(nopend);
1725 return new NodePair(cond.getBegin(), nopend);
1728 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
1729 switch(bsn.kind()) {
1730 case Kind.BlockExpressionNode:
1731 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
1733 case Kind.DeclarationNode:
1734 return flattenDeclarationNode((DeclarationNode)bsn);
1736 case Kind.TagDeclarationNode:
1737 return flattenTagDeclarationNode((TagDeclarationNode)bsn);
1739 case Kind.IfStatementNode:
1740 return flattenIfStatementNode((IfStatementNode)bsn);
1742 case Kind.SwitchStatementNode:
1743 return flattenSwitchStatementNode((SwitchStatementNode)bsn);
1746 return flattenLoopNode((LoopNode)bsn);
1748 case Kind.ReturnNode:
1749 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
1751 case Kind.TaskExitNode:
1752 return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
1754 case Kind.SubBlockNode:
1755 return flattenSubBlockNode((SubBlockNode)bsn);
1757 case Kind.AtomicNode:
1758 return flattenAtomicNode((AtomicNode)bsn);
1760 case Kind.SynchronizedNode:
1761 return flattenSynchronizedNode((SynchronizedNode)bsn);
1764 return flattenSESENode((SESENode)bsn);
1766 case Kind.GenReachNode:
1767 return flattenGenReachNode((GenReachNode)bsn);
1769 case Kind.GenDefReachNode:
1770 return flattenGenDefReachNode((GenDefReachNode)bsn);
1772 case Kind.ContinueBreakNode:
1773 return flattenContinueBreakNode((ContinueBreakNode)bsn);
1778 private void addMapNode2FlatNodeSet(TreeNode tn, FlatNode fn){
1779 Set<FlatNode> fnSet=mapNode2FlatNodeSet.get(tn);
1781 fnSet=new HashSet<FlatNode>();
1782 mapNode2FlatNodeSet.put(tn, fnSet);
1787 public Set<FlatNode> getFlatNodeSet(TreeNode tn){
1788 // WARNING: ONLY DID FOR NAMENODE NOW!
1789 assert(tn instanceof NameNode);
1790 return mapNode2FlatNodeSet.get(tn);