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();
312 if(bn.getLabel()!=null) {
313 // interim implementation to have the labeled statement
314 state.fn2labelMap.put(np_begin, bn.getLabel());
322 end.addNext(np_begin);
324 return new NodePair(begin, null);
330 end=begin=new FlatNop();
332 return new NodePair(begin,end);
335 private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
336 //System.out.println("DEBUG -> inside flattenBlockExpressionNode\n");
337 TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
338 return flattenExpressionNode(en.getExpression(),tmp);
341 private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
342 TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
343 NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
344 FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
345 fcn.setNumLine(cn.getNumLine());
346 np.getEnd().addNext(fcn);
347 return new NodePair(np.getBegin(),fcn);
350 private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
351 FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
352 fln.setNumLine(ln.getNumLine());
353 return new NodePair(fln,fln);
356 private NodePair flattenOffsetNode(OffsetNode ofn, TempDescriptor out_temp) {
357 FlatOffsetNode fln = new FlatOffsetNode(ofn.getClassType(), ofn.getField(), out_temp);
358 fln.setNumLine(ofn.getNumLine());
359 return new NodePair(fln, fln);
362 private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
363 TypeDescriptor td=con.getType();
365 FlatNode fn=new FlatNew(td, out_temp, con.isGlobal(), con.getDisjointId());
367 //handle wrapper fields
368 ClassDescriptor cd=td.getClassDesc();
369 for(Iterator fieldit=cd.getFields(); fieldit.hasNext(); ) {
370 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
371 if (fd.getType().iswrapper()) {
372 TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType());
373 FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal());
374 fnwrapper.setNumLine(con.getNumLine());
375 FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp);
376 fsfn.setNumLine(con.getNumLine());
377 last.addNext(fnwrapper);
378 fnwrapper.addNext(fsfn);
383 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
386 for(int i=0; i<con.numArgs(); i++) {
387 ExpressionNode en=con.getArg(i);
388 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
390 NodePair np=flattenExpressionNode(en, tmp);
391 last.addNext(np.getBegin());
394 MethodDescriptor md=con.getConstructor();
395 //Call to constructor
396 FlatCall fc=new FlatCall(md, null, out_temp, temps);
397 fc.setNumLine(con.getNumLine());
400 if (td.getClassDesc().hasFlags()) {
401 // if (con.getFlagEffects()!=null) {
402 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
403 ffan.setNumLine(con.getNumLine());
404 FlagEffects fes=con.getFlagEffects();
405 TempDescriptor flagtemp=out_temp;
407 for(int j=0; j<fes.numEffects(); j++) {
408 FlagEffect fe=fes.getEffect(j);
409 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
411 for(int j=0; j<fes.numTagEffects(); j++) {
412 TagEffect te=fes.getTagEffect(j);
413 TempDescriptor tagtemp=getTempforVar(te.getTag());
415 ffan.addTagAction(flagtemp, te.getTag().getTag(), tagtemp, te.getStatus());
418 ffan.addFlagAction(flagtemp, null, false);
423 return new NodePair(fn,last);
425 if(con.getArrayInitializer() == null) {
428 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
429 for (int i=0; i<con.numArgs(); i++) {
430 ExpressionNode en=con.getArg(i);
431 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
433 NodePair np=flattenExpressionNode(en, tmp);
437 last.addNext(np.getBegin());
440 TempDescriptor tmp2=(i==0)?
442 TempDescriptor.tempFactory("arg",en.getType());
444 FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal(), con.getDisjointId());
446 if (temps.length>1) {
447 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
448 fn.addNext(np.getBegin());
449 return new NodePair(first,np.getEnd());
450 } else if (td.isArray()&&td.dereference().iswrapper()) {
451 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0, con.isGlobal());
452 fn.addNext(np.getBegin());
453 return new NodePair(first,np.getEnd());
455 return new NodePair(first, fn);
457 // array creation with initializers
458 return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
463 private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i, boolean isglobal) {
464 TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
465 TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
466 FlatNop fnop=new FlatNop(); //last node
469 FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
471 FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
473 TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
475 FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
476 FlatCondBranch fcb=new FlatCondBranch(tmpbool);
477 fcb.setTrueProb(State.TRUEPROB);
480 TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
481 FlatNew fn=td.iswrapper()?new FlatNew(td, new_tmp, isglobal):new FlatNew(td, new_tmp, temparray[i+1], isglobal);
482 FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
484 FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
490 fcb.addFalseNext(fnop);
492 //Recursive call here
493 if ((i+2)<temparray.length) {
494 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
495 fsen.addNext(np2.getBegin());
496 np2.getEnd().addNext(fon);
497 } else if (td.isArray()&&td.dereference().iswrapper()) {
498 NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1, isglobal);
499 fsen.addNext(np2.getBegin());
500 np2.getEnd().addNext(fon);
505 return new NodePair(fln, fnop);
508 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
509 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
512 TempDescriptor thisarg=null;
514 if (min.getExpression()!=null) {
515 TypeDescriptor mtd = min.getExpression().getType();
516 if(mtd.isClass() && mtd.getClassDesc().isEnum()) {
517 mtd = new TypeDescriptor(TypeDescriptor.INT);
519 thisarg=TempDescriptor.tempFactory("thisarg", mtd);
520 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
526 for(int i=0; i<min.numArgs(); i++) {
527 ExpressionNode en=min.getArg(i);
528 TypeDescriptor etd = en.getType();
529 if(etd.isClass() && etd.getClassDesc().isEnum()) {
530 etd = new TypeDescriptor(TypeDescriptor.INT);
532 TempDescriptor td=TempDescriptor.tempFactory("arg", etd);
534 NodePair np=flattenExpressionNode(en, td);
538 last.addNext(np.getBegin());
542 MethodDescriptor md=min.getMethod();
544 //Call to constructor
547 if(md.getReturnType()==null||md.getReturnType().isVoid())
548 fc=new FlatCall(md, null, thisarg, temps, min.getSuper());
550 fc=new FlatCall(md, out_temp, thisarg, temps, min.getSuper());
552 fc.setNumLine(min.getNumLine());
558 return new NodePair(first,fc);
561 private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
562 TempDescriptor tmp=null;
563 if(fan.getExpression().getType().isClassNameRef()) {
564 // static field dereference with class name
565 tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType());
566 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
567 fn.setNumLine(fan.getNumLine());
568 return new NodePair(fn,fn);
570 tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
571 NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
572 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
573 fn.setNumLine(fan.getNumLine());
574 npe.getEnd().addNext(fn);
575 return new NodePair(npe.getBegin(),fn);
579 private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
580 TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
581 TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
582 NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
583 NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
584 TempDescriptor arraytmp=out_temp;
585 if (aan.iswrapper()) {
587 arraytmp=TempDescriptor.tempFactory("temp", aan.getExpression().getType().dereference());
589 FlatNode fn=new FlatElementNode(tmp,tmpindex,arraytmp);
590 fn.setNumLine(aan.getNumLine());
591 npe.getEnd().addNext(npi.getBegin());
592 npi.getEnd().addNext(fn);
593 if (aan.iswrapper()) {
594 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)aan.getExpression().getType().dereference().getClassDesc().getFieldTable().get("value"),arraytmp,out_temp);
595 ffn.setNumLine(aan.getNumLine());
599 return new NodePair(npe.getBegin(),fn);
602 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
604 // left side is variable
605 // left side is field
606 // left side is array
608 Operation base=an.getOperation().getBaseOp();
609 boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC);
612 //rewrite the base operation
613 base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB);
617 TempDescriptor src_tmp = src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType());
620 if (an.getSrc()!=null) {
621 if(an.getSrc().getEval() != null) {
622 FlatLiteralNode fln=new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
623 fln.setNumLine(an.getSrc().getNumLine());
626 NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
627 first=np_src.getBegin();
628 last=np_src.getEnd();
631 FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
632 fln.setNumLine(an.getNumLine());
637 if (an.getDest().kind()==Kind.FieldAccessNode) {
638 //We are assigning an object field
640 FieldAccessNode fan=(FieldAccessNode)an.getDest();
641 ExpressionNode en=fan.getExpression();
642 TempDescriptor dst_tmp=null;
643 NodePair np_baseexp=null;
644 if(en.getType().isClassNameRef()) {
645 // static field dereference with class name
646 dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
647 FlatNop nop=new FlatNop();
648 np_baseexp = new NodePair(nop,nop);
650 dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
651 np_baseexp=flattenExpressionNode(en, dst_tmp);
654 first=np_baseexp.getBegin();
656 last.addNext(np_baseexp.getBegin());
657 last=np_baseexp.getEnd();
659 //See if we need to perform an operation
661 //If it is a preinc we need to store the initial value
662 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
663 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
664 FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
665 ffn.setNumLine(an.getNumLine());
669 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
670 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
671 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
672 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
673 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
674 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
675 fc1.setNumLine(an.getNumLine());
677 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
678 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
679 fc.setNumLine(an.getNumLine());
685 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
686 fon.setNumLine(an.getNumLine());
693 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
694 fsfn.setNumLine(en.getNumLine());
698 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
699 fon2.setNumLine(an.getNumLine());
703 return new NodePair(first, last);
704 } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
705 //We are assigning an array element
707 ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
708 ExpressionNode en=aan.getExpression();
709 ExpressionNode enindex=aan.getIndex();
710 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
711 TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
712 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
713 NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
715 first=np_baseexp.getBegin();
717 last.addNext(np_baseexp.getBegin());
718 np_baseexp.getEnd().addNext(np_indexexp.getBegin());
719 last=np_indexexp.getEnd();
721 //See if we need to perform an operation
723 //If it is a preinc we need to store the initial value
724 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
725 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
727 if (aan.iswrapper()) {
728 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
729 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
730 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
731 fen.setNumLine(aan.getNumLine());
732 FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp3,src_tmp2);
733 ffn.setNumLine(aan.getNumLine());
738 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
739 fen.setNumLine(aan.getNumLine());
743 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
744 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
745 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
746 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
747 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
748 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
749 fc1.setNumLine(an.getNumLine());
751 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
752 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
753 fc.setNumLine(an.getNumLine());
760 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
761 fon.setNumLine(an.getNumLine());
768 if (aan.iswrapper()) {
769 TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
770 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
771 FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
772 fen.setNumLine(aan.getNumLine());
773 FlatSetFieldNode fsfn=new FlatSetFieldNode(src_tmp3,(FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp);
774 fsfn.setNumLine(aan.getExpression().getNumLine());
779 FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
780 fsen.setNumLine(aan.getNumLine());
785 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
786 fon2.setNumLine(an.getNumLine());
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());
859 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
860 fon2.setNumLine(an.getNumLine());
864 return new NodePair(first, last);
866 if (nn.getField()!=null) {
870 //See if we need to perform an operation
872 //If it is a preinc we need to store the initial value
873 TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp;
874 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
876 TempDescriptor ftmp= null;
877 if((nn.getClassDesc() != null)) {
878 // this is a static field
879 ftmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
882 ftmp=getTempforVar(nn.getVar());
884 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), ftmp, src_tmp2);
885 ffn.setNumLine(an.getNumLine());
895 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
896 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
897 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
898 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
899 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
900 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
901 fc1.setNumLine(an.getNumLine());
903 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
904 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
905 fc.setNumLine(an.getNumLine());
911 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
912 fon.setNumLine(an.getNumLine());
919 FlatSetFieldNode fsfn=null;
920 if(nn.getClassDesc()!=null) {
921 // this is a static field access inside of a static block
922 fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
923 fsfn.setNumLine(nn.getNumLine());
925 fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
926 fsfn.setNumLine(nn.getNumLine());
935 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
936 fon2.setNumLine(an.getNumLine());
940 return new NodePair(first, last);
943 //See if we need to perform an operation
946 //If it is a preinc we need to store the initial value
947 TempDescriptor src_tmp2=getTempforVar(nn.getVar());
948 TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
950 FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
951 fon.setNumLine(an.getNumLine());
960 if (base.getOp()==Operation.ADD&&an.getDest().getType().isString()) {
961 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
962 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
963 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
964 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
965 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {src_tmp2});
966 fc1.setNumLine(an.getNumLine());
968 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
969 FlatCall fc=new FlatCall(concatmd, tmp, src_tmp3, new TempDescriptor[] {src_tmp});
970 fc.setNumLine(an.getNumLine());
981 FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
982 fon.setNumLine(an.getNumLine());
992 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
993 fon.setNumLine(an.getNumLine());
998 FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
999 fon2.setNumLine(an.getNumLine());
1003 return new NodePair(first, last);
1011 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
1012 if (nn.getExpression()!=null) {
1013 /* Hack - use subtree instead */
1014 return flattenExpressionNode(nn.getExpression(),out_temp);
1015 } else if (nn.getField()!=null) {
1016 TempDescriptor tmp= null;
1017 if((nn.getClassDesc() != null)) {
1018 // this is a static field
1019 tmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
1022 tmp=getTempforVar(nn.getVar());
1024 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
1025 ffn.setNumLine(nn.getNumLine());
1026 addMapNode2FlatNodeSet(nn,ffn);
1027 return new NodePair(ffn,ffn);
1029 TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
1032 out_temp.setTag(tmp.getTag());
1034 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
1035 fon.setNumLine(nn.getNumLine());
1036 addMapNode2FlatNodeSet(nn,fon);
1037 return new NodePair(fon,fon);
1041 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
1042 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
1043 TempDescriptor temp_right=null;
1045 Operation op=on.getOp();
1047 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
1049 if (on.getRight()!=null) {
1050 temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
1051 right=flattenExpressionNode(on.getRight(),temp_right);
1053 FlatNop nop=new FlatNop();
1054 right=new NodePair(nop,nop);
1057 if (op.getOp()==Operation.LOGIC_OR) {
1058 /* Need to do shortcircuiting */
1059 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1060 fcb.setNumLine(on.getNumLine());
1061 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1062 fon1.setNumLine(on.getNumLine());
1063 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1064 fon2.setNumLine(on.getNumLine());
1065 FlatNop fnop=new FlatNop();
1066 left.getEnd().addNext(fcb);
1067 fcb.addFalseNext(right.getBegin());
1068 right.getEnd().addNext(fon2);
1070 fcb.addTrueNext(fon1);
1072 return new NodePair(left.getBegin(), fnop);
1073 } else if (op.getOp()==Operation.LOGIC_AND) {
1074 /* Need to do shortcircuiting */
1075 FlatCondBranch fcb=new FlatCondBranch(temp_left);
1076 fcb.setNumLine(on.getNumLine());
1077 FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
1078 fon1.setNumLine(on.getNumLine());
1079 FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
1080 fon2.setNumLine(on.getNumLine());
1081 FlatNop fnop=new FlatNop();
1082 left.getEnd().addNext(fcb);
1083 fcb.addTrueNext(right.getBegin());
1084 right.getEnd().addNext(fon2);
1086 fcb.addFalseNext(fon1);
1088 return new NodePair(left.getBegin(), fnop);
1089 } else if (op.getOp()==Operation.ADD&&on.getLeft().getType().isString()) {
1090 //We have a string concatenate
1091 ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
1092 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
1093 TempDescriptor src_tmp3=TempDescriptor.tempFactory("src", new TypeDescriptor(stringcd));
1094 MethodDescriptor valueOfmd=typeutil.getMethod(stringcd, "valueOf", new TypeDescriptor[] {new TypeDescriptor(objectcd)});
1095 FlatCall fc1=new FlatCall(valueOfmd, src_tmp3, null, new TempDescriptor[] {temp_left});
1096 fc1.setNumLine(on.getNumLine());
1098 MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
1099 FlatCall fc=new FlatCall(concatmd, out_temp, src_tmp3, new TempDescriptor[] {temp_right});
1100 fc.setNumLine(on.getNumLine());
1101 left.getEnd().addNext(right.getBegin());
1102 right.getEnd().addNext(fc1);
1104 return new NodePair(left.getBegin(), fc);
1107 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
1108 fon.setNumLine(on.getNumLine());
1109 left.getEnd().addNext(right.getBegin());
1110 right.getEnd().addNext(fon);
1111 return new NodePair(left.getBegin(),fon);
1114 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
1116 case Kind.AssignmentNode:
1117 return flattenAssignmentNode((AssignmentNode)en,out_temp);
1120 return flattenCastNode((CastNode)en,out_temp);
1122 case Kind.CreateObjectNode:
1123 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
1125 case Kind.FieldAccessNode:
1126 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
1128 case Kind.ArrayAccessNode:
1129 return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
1131 case Kind.LiteralNode:
1132 return flattenLiteralNode((LiteralNode)en,out_temp);
1134 case Kind.MethodInvokeNode:
1135 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
1138 return flattenNameNode((NameNode)en,out_temp);
1141 return flattenOpNode((OpNode)en,out_temp);
1143 case Kind.OffsetNode:
1144 return flattenOffsetNode((OffsetNode)en,out_temp);
1146 case Kind.TertiaryNode:
1147 return flattenTertiaryNode((TertiaryNode)en,out_temp);
1149 case Kind.InstanceOfNode:
1150 return flattenInstanceOfNode((InstanceOfNode)en,out_temp);
1152 case Kind.ArrayInitializerNode:
1153 return flattenArrayInitializerNode((ArrayInitializerNode)en,out_temp);
1158 private NodePair flattenDeclarationNode(DeclarationNode dn) {
1159 VarDescriptor vd=dn.getVarDescriptor();
1160 TempDescriptor td=getTempforVar(vd);
1161 if (dn.getExpression()!=null)
1162 return flattenExpressionNode(dn.getExpression(),td);
1164 FlatNop fn=new FlatNop();
1165 return new NodePair(fn,fn);
1169 private NodePair flattenTagDeclarationNode(TagDeclarationNode dn) {
1170 TagVarDescriptor tvd=dn.getTagVarDescriptor();
1171 TagDescriptor tag=tvd.getTag();
1172 TempDescriptor tmp=getTempforVar(tvd);
1173 FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
1174 ftd.setNumLine(dn.getNumLine());
1175 return new NodePair(ftd,ftd);
1178 private TempDescriptor getTempforParam(Descriptor d) {
1179 if (temptovar.containsKey(d))
1180 return (TempDescriptor)temptovar.get(d);
1182 if (d instanceof VarDescriptor) {
1183 VarDescriptor vd=(VarDescriptor)d;
1184 TempDescriptor td=TempDescriptor.paramtempFactory(vd.getName(),vd.getType());
1185 temptovar.put(vd,td);
1187 } else if (d instanceof TagVarDescriptor) {
1188 TagVarDescriptor tvd=(TagVarDescriptor)d;
1189 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1190 TempDescriptor td=TempDescriptor.paramtempFactory(tvd.getName(), tagtype, tvd.getTag());
1191 temptovar.put(tvd,td);
1193 } else throw new Error("Unreconized Descriptor");
1197 private TempDescriptor getTempforVar(Descriptor d) {
1198 if (temptovar.containsKey(d))
1199 return (TempDescriptor)temptovar.get(d);
1201 if (d instanceof VarDescriptor) {
1202 VarDescriptor vd=(VarDescriptor)d;
1203 TempDescriptor td=TempDescriptor.tempFactory(vd.getName(), vd.getType());
1204 temptovar.put(vd,td);
1206 } else if (d instanceof TagVarDescriptor) {
1207 TagVarDescriptor tvd=(TagVarDescriptor)d;
1208 //BUGFIX TAGTYPE - add next line, modify following
1209 //line to tag this new type descriptor, modify
1210 //TempDescriptor constructor & factory to set type
1211 //using this Type To test, use any program with tags
1212 TypeDescriptor tagtype=new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass));
1213 TempDescriptor td=TempDescriptor.tempFactory(tvd.getName(),tagtype, tvd.getTag());
1214 temptovar.put(tvd,td);
1216 } else throw new Error("Unrecognized Descriptor");
1220 private NodePair flattenIfStatementNode(IfStatementNode isn) {
1221 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1222 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
1223 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1224 fcb.setNumLine(isn.getNumLine());
1225 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
1227 FlatNop nopend=new FlatNop();
1229 if (isn.getFalseBlock()!=null)
1230 false_np=flattenBlockNode(isn.getFalseBlock());
1232 FlatNop nop=new FlatNop();
1233 false_np=new NodePair(nop,nop);
1236 cond.getEnd().addNext(fcb);
1237 fcb.addTrueNext(true_np.getBegin());
1238 fcb.addFalseNext(false_np.getBegin());
1239 if (true_np.getEnd()!=null)
1240 true_np.getEnd().addNext(nopend);
1241 if (false_np.getEnd()!=null)
1242 false_np.getEnd().addNext(nopend);
1243 if (nopend.numPrev()==0)
1244 return new NodePair(cond.getBegin(), null);
1246 return new NodePair(cond.getBegin(), nopend);
1249 private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
1250 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
1251 NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
1252 NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp);
1254 cond.getEnd().addNext(sbody.getBegin());
1256 return new NodePair(cond.getBegin(), sbody.getEnd());
1259 private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp) {
1260 FlatNode begin=null;
1262 NodePair prev_true_branch = null;
1263 NodePair prev_false_branch = null;
1264 for(int i=0; i<bn.size(); i++) {
1265 SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
1266 HashSet oldbs=breakset;
1267 breakset=new HashSet();
1269 NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
1270 Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
1271 FlatNode cond_begin = null;
1272 NodePair prev_fnp = null;
1273 for(int j = 0; j < slnv.size(); j++) {
1274 SwitchLabelNode sln = slnv.elementAt(j);
1275 NodePair left = null;
1276 NodePair false_np = null;
1277 if(sln.isDefault()) {
1280 TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1281 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
1282 Operation op=new Operation(Operation.EQUAL);
1283 left=flattenExpressionNode(sln.getCondition(), temp_left);
1284 FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
1285 fon.setNumLine(sln.getNumLine());
1286 left.getEnd().addNext(fon);
1288 FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
1289 fcb.setNumLine(bn.getNumLine());
1290 fcb.setTrueProb(State.TRUEPROB);
1292 FlatNop nop=new FlatNop();
1293 false_np=new NodePair(nop,nop);
1296 fcb.addTrueNext(body.getBegin());
1297 fcb.addFalseNext(false_np.getBegin());
1299 if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
1300 prev_fnp.getEnd().addNext(left.getBegin());
1302 prev_fnp = false_np;
1305 begin = left.getBegin();
1307 if(cond_begin == null) {
1308 cond_begin = left.getBegin();
1311 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1312 prev_false_branch.getEnd().addNext(cond_begin);
1314 prev_false_branch = prev_fnp;
1315 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1316 prev_true_branch.getEnd().addNext(body.getBegin());
1318 prev_true_branch = body;
1319 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1320 FlatNode fn=(FlatNode)breakit.next();
1328 if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
1331 prev_true_branch.getEnd().addNext(end);
1333 if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
1336 prev_false_branch.getEnd().addNext(end);
1339 end=begin=new FlatNop();
1341 return new NodePair(begin,end);
1344 private NodePair flattenLoopNode(LoopNode ln) {
1345 HashSet oldbs=breakset;
1346 HashSet oldcs=continueset;
1347 breakset=new HashSet();
1348 continueset=new HashSet();
1350 if (ln.getType()==LoopNode.FORLOOP) {
1351 NodePair initializer=flattenBlockNode(ln.getInitializer());
1352 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1353 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1354 NodePair update=flattenBlockNode(ln.getUpdate());
1355 NodePair body=flattenBlockNode(ln.getBody());
1356 FlatNode begin=initializer.getBegin();
1357 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1358 fcb.setNumLine(ln.getNumLine());
1359 fcb.setTrueProb(State.TRUEPROB);
1361 FlatNop nopend=new FlatNop();
1362 FlatBackEdge backedge=new FlatBackEdge();
1364 FlatNop nop2=new FlatNop();
1365 initializer.getEnd().addNext(nop2);
1366 nop2.addNext(condition.getBegin());
1367 if (body.getEnd()!=null)
1368 body.getEnd().addNext(update.getBegin());
1369 update.getEnd().addNext(backedge);
1370 backedge.addNext(condition.getBegin());
1371 condition.getEnd().addNext(fcb);
1372 fcb.addFalseNext(nopend);
1373 fcb.addTrueNext(body.getBegin());
1374 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1375 FlatNode fn=(FlatNode)contit.next();
1377 fn.addNext(update.getBegin());
1379 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1380 FlatNode fn=(FlatNode)breakit.next();
1386 return new NodePair(begin,nopend);
1387 } else if (ln.getType()==LoopNode.WHILELOOP) {
1388 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1389 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1390 NodePair body=flattenBlockNode(ln.getBody());
1391 FlatNode begin=condition.getBegin();
1392 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1393 fcb.setNumLine(ln.getNumLine());
1394 fcb.setTrueProb(State.TRUEPROB);
1396 FlatNop nopend=new FlatNop();
1397 FlatBackEdge backedge=new FlatBackEdge();
1399 if (body.getEnd()!=null)
1400 body.getEnd().addNext(backedge);
1401 backedge.addNext(condition.getBegin());
1403 condition.getEnd().addNext(fcb);
1404 fcb.addFalseNext(nopend);
1405 fcb.addTrueNext(body.getBegin());
1407 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1408 FlatNode fn=(FlatNode)contit.next();
1410 fn.addNext(backedge);
1412 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1413 FlatNode fn=(FlatNode)breakit.next();
1419 return new NodePair(begin,nopend);
1420 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
1421 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
1422 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
1423 NodePair body=flattenBlockNode(ln.getBody());
1424 FlatNode begin=body.getBegin();
1425 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1426 fcb.setNumLine(ln.getNumLine());
1427 fcb.setTrueProb(State.TRUEPROB);
1429 FlatNop nopend=new FlatNop();
1430 FlatBackEdge backedge=new FlatBackEdge();
1432 if (body.getEnd()!=null)
1433 body.getEnd().addNext(condition.getBegin());
1434 condition.getEnd().addNext(fcb);
1435 fcb.addFalseNext(nopend);
1436 fcb.addTrueNext(backedge);
1437 backedge.addNext(body.getBegin());
1439 for(Iterator contit=continueset.iterator(); contit.hasNext(); ) {
1440 FlatNode fn=(FlatNode)contit.next();
1442 fn.addNext(condition.getBegin());
1444 for(Iterator breakit=breakset.iterator(); breakit.hasNext(); ) {
1445 FlatNode fn=(FlatNode)breakit.next();
1451 return new NodePair(begin,nopend);
1452 } else throw new Error();
1455 private NodePair flattenReturnNode(ReturnNode rntree) {
1456 TempDescriptor retval=null;
1458 if (rntree.getReturnExpression()!=null) {
1459 retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
1460 cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
1463 FlatReturnNode rnflat=new FlatReturnNode(retval);
1464 rnflat.setNumLine(rntree.getNumLine());
1467 if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
1469 //XXXXXXXXX: FIX THIS
1471 FlatNode end = null;
1472 MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1473 for(int j = this.lockStack.size(); j > 0; j--) {
1474 TempDescriptor thistd = this.lockStack.elementAt(j-1);
1475 FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
1476 fcunlock.setNumLine(rntree.getNumLine());
1478 end.addNext(fcunlock);
1486 if (state.DSM&&currmd.getModifiers().isAtomic()) {
1487 FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
1493 cond.getEnd().addNext(ln);
1494 return new NodePair(cond.getBegin(),null);
1496 return new NodePair(ln,null);
1499 private NodePair flattenTaskExitNode(TaskExitNode ten) {
1500 FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.TASKEXIT);
1501 ffan.setTaskExitIndex(ten.getTaskExitIndex());
1502 updateFlagActionNode(ffan, ten.getFlagEffects());
1503 NodePair fcn=flattenConstraintCheck(ten.getChecks());
1504 ffan.addNext(fcn.getBegin());
1505 FlatReturnNode rnflat=new FlatReturnNode(null);
1506 rnflat.setNumLine(ten.getNumLine());
1508 fcn.getEnd().addNext(rnflat);
1509 return new NodePair(ffan, null);
1512 private NodePair flattenConstraintCheck(Vector ccs) {
1513 FlatNode begin=new FlatNop();
1515 return new NodePair(begin,begin);
1516 FlatNode last=begin;
1517 for(int i=0; i<ccs.size(); i++) {
1518 ConstraintCheck cc=(ConstraintCheck) ccs.get(i);
1519 /* Flatten the arguments */
1520 TempDescriptor[] temps=new TempDescriptor[cc.numArgs()];
1521 String[] vars=new String[cc.numArgs()];
1522 for(int j=0; j<cc.numArgs(); j++) {
1523 ExpressionNode en=cc.getArg(j);
1524 TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
1526 vars[j]=cc.getVar(j);
1527 NodePair np=flattenExpressionNode(en, td);
1528 last.addNext(np.getBegin());
1532 FlatCheckNode fcn=new FlatCheckNode(cc.getSpec(), vars, temps);
1536 return new NodePair(begin,last);
1539 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
1540 return flattenBlockNode(sbn.getBlockNode());
1543 private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
1544 TempDescriptor montmp=null;
1545 FlatNode first = null;
1546 FlatNode end = null;
1547 if(sbn.getExpr() instanceof ClassTypeNode) {
1548 montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
1550 montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
1551 NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
1552 first = npexp.getBegin();
1553 end = npexp.getEnd();
1555 this.lockStack.push(montmp);
1556 NodePair npblock=flattenBlockNode(sbn.getBlockNode());
1558 this.lockStack.pop();
1561 MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
1562 FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
1563 fcen.setNumLine(sbn.getNumLine());
1565 MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
1566 FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
1567 fcex.setNumLine(sbn.getNumLine());
1569 this.lockStack.pop();
1576 fcen.addNext(npblock.getBegin());
1578 if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
1579 npblock.getEnd().addNext(fcex);
1580 return new NodePair(first, fcex);
1582 return new NodePair(first, null);
1587 private NodePair flattenAtomicNode(AtomicNode sbn) {
1588 NodePair np=flattenBlockNode(sbn.getBlockNode());
1589 FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
1590 faen.setNumLine(sbn.getNumLine());
1591 FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
1592 faen.addNext(np.getBegin());
1593 np.getEnd().addNext(faexn);
1594 return new NodePair(faen, faexn);
1597 private NodePair flattenGenReachNode(GenReachNode grn) {
1598 FlatGenReachNode fgrn = new FlatGenReachNode(grn.getGraphName() );
1599 return new NodePair(fgrn, fgrn);
1602 private NodePair flattenSESENode(SESENode sn) {
1603 if( sn.isStart() ) {
1604 FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
1605 fsen.setNumLine(sn.getNumLine());
1606 sn.setFlatEnter(fsen);
1607 return new NodePair(fsen, fsen);
1610 FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
1611 sn.setFlatExit(fsexn);
1612 FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
1613 fsexn.setFlatEnter(fsen);
1614 sn.getStart().getFlatEnter().setFlatExit(fsexn);
1616 return new NodePair(fsexn, fsexn);
1619 private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
1620 FlatNop fn=new FlatNop();
1624 continueset.add(fn);
1625 return new NodePair(fn,null);
1628 private NodePair flattenInstanceOfNode(InstanceOfNode tn, TempDescriptor out_temp) {
1629 TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
1630 NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
1631 FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
1632 fion.setNumLine(tn.getNumLine());
1633 cond.getEnd().addNext(fion);
1634 return new NodePair(cond.getBegin(),fion);
1637 private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
1638 boolean isGlobal = false;
1639 String disjointId = null;
1640 // get the type the array to be initialized
1641 TypeDescriptor td = ain.getType();
1643 // create a new array of size equal to the array initializer
1644 FlatNode first=null;
1646 TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
1647 FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
1648 fln_tmp.setNumLine(ain.getNumLine());
1649 first = last=fln_tmp;
1651 // create the new array
1652 FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
1656 // initialize the new array
1657 for(int i = 0; i < ain.numVarInitializers(); i++) {
1658 ExpressionNode var_init_node = ain.getVarInitializer(i);
1659 TempDescriptor tmp_toinit = out_temp;
1660 TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
1662 TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
1663 FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
1664 fln.setNumLine(ain.getNumLine());
1665 // calculate the initial value
1666 NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
1667 // TODO wrapper class process is missing now
1668 /*if(td.isArray() && td.dereference().iswrapper()) {
1670 FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
1671 fsen.setNumLine(ain.getNumLine());
1673 fln.addNext(np_init.getBegin());
1674 np_init.getEnd().addNext(fsen);
1678 return new NodePair(first, last);
1681 private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
1682 TempDescriptor cond_temp=TempDescriptor.tempFactory("tert_cond",new TypeDescriptor(TypeDescriptor.BOOLEAN));
1683 TempDescriptor true_temp=TempDescriptor.tempFactory("tert_true",tn.getTrueExpr().getType());
1684 TempDescriptor fals_temp=TempDescriptor.tempFactory("tert_fals",tn.getFalseExpr().getType());
1686 NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
1687 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
1688 fcb.setNumLine(tn.getNumLine());
1690 NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
1691 FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
1692 fonT.setNumLine(tn.getNumLine());
1694 NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
1695 FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
1696 fonF.setNumLine(tn.getNumLine());
1698 FlatNop nopend=new FlatNop();
1700 cond.getEnd().addNext(fcb);
1702 fcb.addTrueNext(trueExpr.getBegin());
1703 fcb.addFalseNext(falseExpr.getBegin());
1705 trueExpr.getEnd().addNext(fonT);
1706 fonT.addNext(nopend);
1708 falseExpr.getEnd().addNext(fonF);
1709 fonF.addNext(nopend);
1711 return new NodePair(cond.getBegin(), nopend);
1714 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
1715 switch(bsn.kind()) {
1716 case Kind.BlockExpressionNode:
1717 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
1719 case Kind.DeclarationNode:
1720 return flattenDeclarationNode((DeclarationNode)bsn);
1722 case Kind.TagDeclarationNode:
1723 return flattenTagDeclarationNode((TagDeclarationNode)bsn);
1725 case Kind.IfStatementNode:
1726 return flattenIfStatementNode((IfStatementNode)bsn);
1728 case Kind.SwitchStatementNode:
1729 return flattenSwitchStatementNode((SwitchStatementNode)bsn);
1732 return flattenLoopNode((LoopNode)bsn);
1734 case Kind.ReturnNode:
1735 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
1737 case Kind.TaskExitNode:
1738 return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
1740 case Kind.SubBlockNode:
1741 return flattenSubBlockNode((SubBlockNode)bsn);
1743 case Kind.AtomicNode:
1744 return flattenAtomicNode((AtomicNode)bsn);
1746 case Kind.SynchronizedNode:
1747 return flattenSynchronizedNode((SynchronizedNode)bsn);
1750 return flattenSESENode((SESENode)bsn);
1752 case Kind.GenReachNode:
1753 return flattenGenReachNode((GenReachNode)bsn);
1755 case Kind.ContinueBreakNode:
1756 return flattenContinueBreakNode((ContinueBreakNode)bsn);
1761 private void addMapNode2FlatNodeSet(TreeNode tn, FlatNode fn){
1762 Set<FlatNode> fnSet=mapNode2FlatNodeSet.get(tn);
1764 fnSet=new HashSet<FlatNode>();
1765 mapNode2FlatNodeSet.put(tn, fnSet);
1770 public Set<FlatNode> getFlatNodeSet(TreeNode tn){
1771 // WARNING: ONLY DID FOR NAMENODE NOW!
1772 assert(tn instanceof NameNode);
1773 return mapNode2FlatNodeSet.get(tn);