Fix the bug of assignment conversion: 'short s = 12' should be allowed. And for such...
[IRC.git] / Robust / src / IR / Flat / BuildFlat.java
index 5c70bf8b1bcaa603f47dd3cac1cb487e9a7aac1f..c9f4b783de711176f69ab93eff5c4840b864add2 100644 (file)
@@ -1,6 +1,7 @@
 package IR.Flat;
 import IR.*;
 import IR.Tree.*;
+
 import java.util.*;
 
 public class BuildFlat {
@@ -190,7 +191,7 @@ public class BuildFlat {
        curran=null;
       NodePair np=flattenBlockNode(bn);
       FlatNode fn=np.getBegin();
-      if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
+      if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
        MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
        TempDescriptor thistd=getTempforVar(currmd.getThis());
        FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
@@ -359,6 +360,7 @@ public class BuildFlat {
       }
       return new NodePair(fn,last);
     } else {
+      if(con.getArrayInitializer() == null) {
       FlatNode first=null;
       FlatNode last=null;
       TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
@@ -389,6 +391,11 @@ public class BuildFlat {
        return new NodePair(first,np.getEnd());
       } else
        return new NodePair(first, fn);
+      } else if(state.MGC) {
+      // array creation with initializers
+        return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
+      }
+      return null;
     }
   }
 
@@ -480,11 +487,19 @@ public class BuildFlat {
   }
 
   private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
-    TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
-    NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
-    FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
-    npe.getEnd().addNext(fn);
-    return new NodePair(npe.getBegin(),fn);
+    TempDescriptor tmp=null;
+    if(fan.getExpression().getType().isStatic()) {
+      // static field dereference with class name
+      tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType());
+      FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
+      return new NodePair(fn,fn);
+    } else {
+      tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
+      NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
+      FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
+      npe.getEnd().addNext(fn);
+      return new NodePair(npe.getBegin(),fn);
+    }
   }
 
   private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
@@ -527,9 +542,13 @@ public class BuildFlat {
 
     //Get src value
     if (an.getSrc()!=null) {
-      NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
-      first=np_src.getBegin();
-      last=np_src.getEnd();
+      if(an.getSrc().getEval() != null) {
+        first = last = new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
+      } else {
+        NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
+        first=np_src.getBegin();
+        last=np_src.getEnd();
+      }
     } else if (!pre) {
       FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
       first=fln;
@@ -541,8 +560,17 @@ public class BuildFlat {
 
       FieldAccessNode fan=(FieldAccessNode)an.getDest();
       ExpressionNode en=fan.getExpression();
-      TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
-      NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+      TempDescriptor dst_tmp=null;
+      NodePair np_baseexp=null;
+      if(en.getType().isStatic()) {
+        // static field dereference with class name
+        dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
+        FlatNop nop=new FlatNop();
+        np_baseexp = new NodePair(nop,nop);
+      } else {
+        dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
+        np_baseexp=flattenExpressionNode(en, dst_tmp);
+      }
       if (first==null)
        first=np_baseexp.getBegin();
       else
@@ -661,8 +689,17 @@ public class BuildFlat {
        //It is a field
        FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
        ExpressionNode en=fan.getExpression();
-       TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
-       NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+    TempDescriptor dst_tmp=null;
+    NodePair np_baseexp=null;
+    if(en.getType().isStatic()) {
+      // static field dereference with class name
+      dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
+      FlatNop nop=new FlatNop();
+      np_baseexp = new NodePair(nop,nop);
+    } else {
+      dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
+      np_baseexp=flattenExpressionNode(en, dst_tmp);
+    }
        if (first==null)
          first=np_baseexp.getBegin();
        else
@@ -740,7 +777,13 @@ public class BuildFlat {
            }
          }
 
-         FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
+      FlatSetFieldNode fsfn=null;
+      if(nn.getClassDesc()!=null) {
+        // this is a static field access inside of a static block
+        fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
+      } else {
+        fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
+      }
          if (first==null) {
            first=fsfn;
          } else {
@@ -1018,7 +1061,95 @@ public class BuildFlat {
 
     return new NodePair(cond.getBegin(), nopend);
   }
+  
+  private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
+    TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
+    NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
+    FlatNop nopend=new FlatNop();
+    NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp, nopend);
+    
+    cond.getEnd().addNext(sbody.getBegin());
 
+    return new NodePair(cond.getBegin(), sbody.getEnd());
+  }
+  
+  private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp, FlatNode endnode) {
+    FlatNode begin=null;
+    FlatNode end=endnode;
+    NodePair prev_true_branch = null;
+    NodePair prev_false_branch = null;
+    for(int i=0; i<bn.size(); i++) {
+      SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
+      HashSet oldbs=breakset;
+      breakset=new HashSet();
+      
+      NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
+      Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
+      FlatNode cond_begin = null;
+      NodePair prev_fnp = null;
+      for(int j = 0; j < slnv.size(); j++) {
+        SwitchLabelNode sln = slnv.elementAt(j);
+        NodePair left = null;
+        NodePair false_np = null;
+        if(sln.isDefault()) {
+          left = body;
+        } else {
+          TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
+          TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
+          Operation op=new Operation(Operation.EQUAL);
+          left=flattenExpressionNode(sln.getCondition(), temp_left);
+          FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
+          left.getEnd().addNext(fon);
+
+          FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
+          fcb.setTrueProb(State.TRUEPROB);
+
+          FlatNop nop=new FlatNop();
+          false_np=new NodePair(nop,nop);
+
+          fon.addNext(fcb);
+          fcb.addTrueNext(body.getBegin());
+          fcb.addFalseNext(false_np.getBegin());
+        }
+        if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
+          prev_fnp.getEnd().addNext(left.getBegin());
+        }
+        prev_fnp = false_np;
+        
+        if (begin==null) {
+          begin = left.getBegin();
+        }
+        if(cond_begin == null) {
+          cond_begin = left.getBegin();
+        }
+      }
+      if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
+        prev_false_branch.getEnd().addNext(cond_begin);
+      }
+      prev_false_branch = prev_fnp;
+      if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
+        prev_true_branch.getEnd().addNext(body.getBegin());
+      }
+      prev_true_branch = body;
+      for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
+        FlatNode fn=(FlatNode)breakit.next();
+        breakit.remove();
+        fn.addNext(endnode);
+      }
+      breakset=oldbs;
+    }
+    if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
+      prev_true_branch.getEnd().addNext(endnode);
+    }
+    if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
+      prev_false_branch.getEnd().addNext(endnode);
+    }
+    if(begin == null) {
+      end=begin=new FlatNop();
+    }
+    return new NodePair(begin,end);
+  }
+  
   private NodePair flattenLoopNode(LoopNode ln) {
     HashSet oldbs=breakset;
     HashSet oldcs=continueset;
@@ -1138,7 +1269,7 @@ public class BuildFlat {
     FlatReturnNode rnflat=new FlatReturnNode(retval);
     rnflat.addNext(fe);
     FlatNode ln=rnflat;
-    if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
+    if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
       MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
       TempDescriptor thistd=getTempforVar(currmd.getThis());
       FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
@@ -1266,43 +1397,44 @@ public class BuildFlat {
   }
 
   private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
-    /*
-    TempDescriptor expr_temp=TempDescriptor.tempFactory("arry_init",ain.getType());
+    boolean isGlobal = false;
+    String disjointId = null;
+    // get the type the array to be initialized
+    TypeDescriptor td = ain.getType();
 
     // create a new array of size equal to the array initializer
-    //FlatNode first=null;
-    //FlatNode last=null;
-    TempDescriptor[] temps=new TempDescriptor[ain.numVarInitializers()];
-
-      for (int i=0; i<con.numArgs(); i++) {
-       ExpressionNode en=con.getArg(i);
-       TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
-       temps[i]=tmp;
-       NodePair np=flattenExpressionNode(en, tmp);
-       if (first==null)
-         first=np.getBegin();
-       else
-         last.addNext(np.getBegin());
-       last=np.getEnd();
-
-       TempDescriptor tmp2=(i==0) ?
-                            out_temp :
-                            TempDescriptor.tempFactory("arg",en.getType());
-      }
-      FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal(), con.getDisjointId());
-      last.addNext(fn);
-
-
-    // assign each element of the new array to the flattened expression
-
-
-    FlatOpNode fonAssignArray=new FlatOpNode(out_temp, newarry_temp, null, new Operation(Operation.ASSIGN));
-    */
-    //return new NodePair( , fonAssignArray );
-    ain.printNode(0);
-    System.out.println( "Array initializers not implemented yet." );
-    System.exit( -1 );
-    return null;
+    FlatNode first=null;
+    FlatNode last=null;
+    TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
+    FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
+    first = last=fln_tmp;
+    
+    // create the new array
+    FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
+    last.addNext(fn);
+    last = fn;
+    
+    // initialize the new array
+    for(int i = 0; i < ain.numVarInitializers(); i++) {
+      ExpressionNode var_init_node = ain.getVarInitializer(i);
+      TempDescriptor tmp_toinit = out_temp;
+      TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
+      // index=i
+      TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
+      FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
+      // calculate the initial value
+      NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
+      // TODO wrapper class process is missing now
+      /*if(td.isArray() && td.dereference().iswrapper()) {
+      }*/
+      FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
+      last.addNext(fln);
+      fln.addNext(np_init.getBegin());
+      np_init.getEnd().addNext(fsen);
+      last = fsen;
+    }
+    
+    return new NodePair(first, last);
   }
 
   private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
@@ -1348,6 +1480,9 @@ public class BuildFlat {
 
     case Kind.IfStatementNode:
       return flattenIfStatementNode((IfStatementNode)bsn);
+      
+    case Kind.SwitchStatementNode:
+      return flattenSwitchStatementNode((SwitchStatementNode)bsn);
 
     case Kind.LoopNode:
       return flattenLoopNode((LoopNode)bsn);