rest of new build strategrest of new build strategyy
authorbdemsky <bdemsky>
Thu, 21 Apr 2011 08:59:10 +0000 (08:59 +0000)
committerbdemsky <bdemsky>
Thu, 21 Apr 2011 08:59:10 +0000 (08:59 +0000)
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/JavaBuilder.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Main/Main.java

index 4b7603a09d26bdbc908d3bd19b1e7d8f113d2ece..087415d05f41eb16c7b03a21e3e9b5587a48e47a 100644 (file)
@@ -14,7 +14,7 @@ public class BuildIR {
   }
 
   public void buildtree(ParseNode pn, Set toanalyze, String sourcefile) {
-    parseFile(pn, toanalyze,sourcefile);
+    parseFile(pn, toanalyze, sourcefile);
     
     // numering the interfaces
     int if_num = 0;
@@ -32,8 +32,8 @@ public class BuildIR {
   NameDescriptor packages;
 
   /** Parse the classes in this file */
-  public void parseFile(ParseNode pn, Set toanalyze,String sourcefile) {
-    singleimports= new Hashtable();
+  public void parseFile(ParseNode pn, Set toanalyze, String sourcefile) {
+    singleimports=new Hashtable();
     multiimports=new Vector();
     ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
     if (ipn!=null) {
@@ -44,13 +44,13 @@ public class BuildIR {
        // TODO need to implement
        if (isNode(pnimport,"import_single"))
          if(!singleimports.containsKey(nd.getIdentifier())) {
-      //map name to full name (includes package/directory
-      singleimports.put(nd.getIdentifier(), nd.getPathFromRootToHere(nd.getIdentifier()));
-    } else {
-      throw new Error("Error: class " + nd.getIdentifier() + " is already more than once in a single type import inside "+sourcefile);
-    }
+           //map name to full name (includes package/directory
+           singleimports.put(nd.getIdentifier(), nd.getPathFromRootToHere(nd.getIdentifier()));
+         } else {
+           throw new Error("Error: class " + nd.getIdentifier() + " is already more than once in a single type import inside "+sourcefile);
+         }
        else
-       //TODO MULTI-IMPORTS!
+         //TODO MULTI-IMPORTS!
          multiimports.add(nd);
       }
     }
@@ -71,7 +71,6 @@ public class BuildIR {
           continue;
         if (isNode(type_pn, "class_declaration")) {
           ClassDescriptor cn = parseTypeDecl(type_pn, packageName);
-          cn.setImports(singleimports, multiimports);
           cn.setSourceFileName(sourcefile);
           parseInitializers(cn);
           if (toanalyze != null)
@@ -179,6 +178,7 @@ public class BuildIR {
   
   private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
     ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+    ecd.setImports(singleimports, multiimports);
     ecd.setAsEnum();
     if(cn != null) {
       ecd.setSurroundingClass(cn.getSymbol());
@@ -213,6 +213,7 @@ public class BuildIR {
   
   public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
+    cn.setImports(singleimports, multiimports);
     //cn.setAsInterface();
     if (!isEmpty(pn.getChild("superIF").getTerminal())) {
       /* parse inherited interface name */
@@ -454,6 +455,7 @@ public class BuildIR {
       String newClassname = packageName + "___________" + pn.getChild("name").getTerminal();
       cn= new ClassDescriptor(packageName, newClassname.replaceAll("\\.", "___________") , false);
     }
+    cn.setImports(singleimports, multiimports);
     if (!isEmpty(pn.getChild("super").getTerminal())) {
       /* parse superclass name */
       ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
@@ -587,6 +589,7 @@ public class BuildIR {
   
   private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) {
     ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+    icn.setImports(singleimports, multiimports);
     icn.setAsInnerClass();
     icn.setSurroundingClass(cn.getSymbol());
     icn.setSurrounding(cn);
@@ -861,6 +864,7 @@ public class BuildIR {
       TypeDescriptor td=parseTypeDescriptor(pn);
       innerCount++;
       ClassDescriptor cnnew=new ClassDescriptor(td.getSymbol()+"$"+innerCount, false);
+      cnnew.setImports(singleimports, multiimports);
       cnnew.setSuper(td.getSymbol());
       parseClassBody(cnnew, pn.getChild("decl").getChild("classbody"));
       Vector args=parseArgumentList(pn);
@@ -957,8 +961,8 @@ public class BuildIR {
       return aan;
     } else if (isNode(pn,"cast1")) {
       try {
-  CastNode cn=new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
-  cn.setNumLine(pn.getLine());      
+       CastNode cn=new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
+       cn.setNumLine(pn.getLine());      
        return cn;
       } catch (Exception e) {
        System.out.println(pn.PPrint(1,true));
index d9aabf11a1a4e58cf716b6efca69c5840979058d..3e6ba16544f24e7cb43d7431452fd2817e35b519 100644 (file)
@@ -5,8 +5,9 @@ import IR.Flat.*;
 import java.util.*;
 import java.io.*;
 import Util.Pair;
+import Analysis.CallGraph.CallGraph;
 
-public class JavaBuilder {
+public class JavaBuilder implements CallGraph {
   State state;
   HashSet<Descriptor> checkedDesc=new HashSet<Descriptor>();
   HashMap<ClassDescriptor, Integer> classStatus=new HashMap<ClassDescriptor, Integer>();
@@ -19,6 +20,8 @@ public class JavaBuilder {
   BuildFlat bf;
   Stack<MethodDescriptor> toprocess=new Stack<MethodDescriptor>();
   HashSet<MethodDescriptor> discovered=new HashSet<MethodDescriptor>();
+  HashMap<MethodDescriptor, Set<MethodDescriptor>> canCall=new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
+  MethodDescriptor mainMethod;
 
   /* Maps class/interfaces to all instantiated classes that extend or
    * implement those classes or interfaces */
@@ -29,9 +32,82 @@ public class JavaBuilder {
   
   HashMap<MethodDescriptor, Set<MethodDescriptor>> callMap=new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
 
+  HashMap<MethodDescriptor, Set<MethodDescriptor>> revCallMap=new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
+
   /* Invocation map */
   HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>> invocationMap=new HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>>();
+
+  public Set getAllMethods(Descriptor d) {
+    HashSet tovisit=new HashSet();
+    tovisit.add(d);
+    HashSet callable=new HashSet();
+    while(!tovisit.isEmpty()) {
+      Descriptor md=(Descriptor)tovisit.iterator().next();
+      tovisit.remove(md);
+      Set s=getCalleeSet(md);
+      
+      if (s!=null) {
+       for(Iterator it=s.iterator(); it.hasNext();) {
+         MethodDescriptor md2=(MethodDescriptor)it.next();
+         if( !callable.contains(md2) ) {
+           callable.add(md2);
+           tovisit.add(md2);
+         }
+       }
+      }
+    }
+    return callable;
+  }
+
+  public Set getMethods(MethodDescriptor md, TypeDescriptor type) {
+    if (canCall.containsKey(md))
+      return canCall.get(md);
+    else
+      return new HashSet();
+  }
+
+  public Set getMethods(MethodDescriptor md) {
+    return getMethods(md, null);
+  }
+
+  public Set getMethodCalls(Descriptor d) {
+    Set set=getAllMethods(d);
+    set.add(d);
+    return set;
+  }
   
+  public boolean isCalled(MethodDescriptor md) {
+    return !getMethods(md).isEmpty();
+  }
+
+  public boolean isCallable(MethodDescriptor md) {
+    return !getCallerSet(md).isEmpty()||md==mainMethod;
+  }
+
+  public Set getCalleeSet(Descriptor d) {
+    Set calleeset=callMap.get((MethodDescriptor)d);
+    if (calleeset==null)
+      return new HashSet();
+    else
+      return calleeset;
+  }
+
+  public Set getCallerSet(MethodDescriptor md) {
+    Set callerset=revCallMap.get(md);
+    if (callerset==null)
+      return new HashSet();
+    else
+      return callerset;
+  }
+
+  public Set getFirstReachableMethodContainingSESE(Descriptor d,
+      Set<MethodDescriptor> methodsContainingSESEs) {
+    throw new Error("");
+  }
+
+  public boolean hasLayout(ClassDescriptor cd) {
+    return sc.hasLayout(cd);
+  }
 
   public JavaBuilder(State state) {
     this.state=state;
@@ -50,10 +126,19 @@ public class JavaBuilder {
   }
 
   public void build() {
+    //Initialize Strings to keep runtime happy
+    ClassDescriptor stringClass=sc.getClass(null, TypeUtil.StringClass, SemanticCheck.INIT);
+    instantiateClass(stringClass);
+
     ClassDescriptor mainClass=sc.getClass(null, state.main, SemanticCheck.INIT);
-    MethodDescriptor mainMethod=tu.getMain();
+    mainMethod=tu.getMain();
+
+    canCall.put(mainMethod, new HashSet<MethodDescriptor>());
+    canCall.get(mainMethod).add(mainMethod);
+
     toprocess.push(mainMethod);
     computeFixPoint();
+    tu.createFullTable();
   }
 
   void checkMethod(MethodDescriptor md) {
@@ -65,10 +150,20 @@ public class JavaBuilder {
     }
   }
   
-  void initClassDesc(ClassDescriptor cd) {
-    if (classStatus.get(cd)==null) {
-      classStatus.put(cd, CDINIT);
-      //TODO...LOOK FOR STATIC INITIALIZERS
+  public boolean isInit(ClassDescriptor cd) {
+    return classStatus.get(cd)!=null&&classStatus.get(cd)>=CDINIT;
+  }
+
+  void initClassDesc(ClassDescriptor cd, int init) {
+    if (classStatus.get(cd)==null||classStatus.get(cd)!=init) {
+      if (classStatus.get(cd)==null) {
+        MethodDescriptor mdstaticinit = (MethodDescriptor)cd.getMethodTable().get("staticblocks");
+       if (mdstaticinit!=null) {
+         discovered.add(mdstaticinit);
+         toprocess.push(mdstaticinit);
+       }
+      }
+      classStatus.put(cd, init);
     }
   }
   
@@ -76,14 +171,21 @@ public class JavaBuilder {
     while(!toprocess.isEmpty()) {
       MethodDescriptor md=toprocess.pop();
       checkMethod(md);
-      initClassDesc(md.getClassDesc());
+      initClassDesc(md.getClassDesc(), CDINIT);
       bf.flattenMethod(md.getClassDesc(), md);
       processFlatMethod(md);
     }
+
+    //make sure every called method descriptor has a flat method
+    for(MethodDescriptor callmd:canCall.keySet())
+      bf.addJustFlatMethod(callmd);
   }
   
   void processCall(MethodDescriptor md, FlatCall fcall) {
     MethodDescriptor callmd=fcall.getMethod();
+    //make sure we have a FlatMethod for the base method...
+    if (!canCall.containsKey(callmd))
+      canCall.put(callmd, new HashSet<MethodDescriptor>());
 
     //First handle easy cases...
     if (callmd.isStatic()||callmd.isConstructor()) {
@@ -91,7 +193,11 @@ public class JavaBuilder {
        discovered.add(callmd);
        toprocess.push(callmd);
       }
+      if (!revCallMap.containsKey(callmd))
+       revCallMap.put(callmd, new HashSet<MethodDescriptor>());
+      revCallMap.get(callmd).add(md);
       callMap.get(md).add(callmd);
+      canCall.get(callmd).add(callmd);
       return;
     }
 
@@ -102,28 +208,35 @@ public class JavaBuilder {
     if (!invocationMap.containsKey(cn))
       invocationMap.put(cn, new HashSet<Pair<MethodDescriptor,MethodDescriptor>>());
     invocationMap.get(cn).add(new Pair<MethodDescriptor, MethodDescriptor>(md, callmd));
+    
+    if (impSet!=null) {
+      for(ClassDescriptor cdactual:impSet) {
+       searchimp:
+       while(cdactual!=null) {
+         Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol());
+         
+         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+           if (callmd.matches(matchmd)) {
+             //Found the method that will be called
+             if (!discovered.contains(matchmd)) {
+               discovered.add(matchmd);
+               toprocess.push(matchmd);
+             }
+
+             if (!revCallMap.containsKey(matchmd))
+               revCallMap.put(matchmd, new HashSet<MethodDescriptor>());
+             revCallMap.get(matchmd).add(md);
 
-    for(ClassDescriptor cdactual:impSet) {
-      searchimp:
-      while(cdactual!=null) {
-       Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol());
-
-       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
-         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
-         if (callmd.matches(matchmd)) {
-           //Found the method that will be called
-           if (!discovered.contains(matchmd)) {
-             discovered.add(matchmd);
-             toprocess.push(matchmd);
+             callMap.get(md).add(matchmd);
+             canCall.get(callmd).add(matchmd);
+             break searchimp;
            }
-           callMap.get(md).add(matchmd);
-           
-           break searchimp;
          }
+         
+         //Didn't find method...look in super class
+         cdactual=cdactual.getSuperDesc();
        }
-
-       //Didn't find method...look in super class
-       cdactual=cdactual.getSuperDesc();
       }
     }
   }
@@ -133,6 +246,16 @@ public class JavaBuilder {
     if (!tdnew.isClass())
       return;
     ClassDescriptor cdnew=tdnew.getClassDesc();
+    //Make sure class is fully initialized
+    sc.checkClass(cdnew, SemanticCheck.INIT);
+    instantiateClass(cdnew);
+  }
+
+  void instantiateClass(ClassDescriptor cdnew) {
+    if (classStatus.containsKey(cdnew)&&classStatus.get(cdnew)==CDINSTANTIATED)
+      return;
+    initClassDesc(cdnew, CDINSTANTIATED);
+
     Stack<ClassDescriptor> tovisit=new Stack<ClassDescriptor>();
     tovisit.add(cdnew);
     
@@ -159,7 +282,11 @@ public class JavaBuilder {
                    discovered.add(matchmd);
                    toprocess.push(matchmd);
                  }
+                 if (!revCallMap.containsKey(matchmd))
+                   revCallMap.put(matchmd, new HashSet<MethodDescriptor>());
+                 revCallMap.get(matchmd).add(md);
                  callMap.get(md).add(matchmd);
+                 canCall.get(callmd).add(matchmd);
                  break searchimp;
                }
              }
@@ -199,46 +326,4 @@ public class JavaBuilder {
       }
     }
   }
-
-  public static ParseNode readSourceFile(State state, String sourcefile) {
-    try {
-      Reader fr= new BufferedReader(new FileReader(sourcefile));
-      Lex.Lexer l = new Lex.Lexer(fr);
-      java_cup.runtime.lr_parser g;
-      g = new Parse.Parser(l);
-      ParseNode p=null;
-      try {
-       p=(ParseNode) g./*debug_*/parse().value;
-      } catch (Exception e) {
-       System.err.println("Error parsing file:"+sourcefile);
-       e.printStackTrace();
-       System.exit(-1);
-      }
-      state.addParseNode(p);
-      if (l.numErrors()!=0) {
-       System.out.println("Error parsing "+sourcefile);
-       System.exit(l.numErrors());
-      }
-      state.lines+=l.line_num;
-      return p;
-
-    } catch (Exception e) {
-      throw new Error(e);
-    }
-  }
-
-  public void loadClass(BuildIR bir, String sourcefile) {
-    try {
-      ParseNode pn=readSourceFile(state, sourcefile);
-      bir.buildtree(pn, null,sourcefile);
-    } catch (Exception e) {
-      System.out.println("Error in sourcefile:"+sourcefile);
-      e.printStackTrace();
-      System.exit(-1);
-    } catch (Error e) {
-      System.out.println("Error in sourcefile:"+sourcefile);
-      e.printStackTrace();
-      System.exit(-1);
-    }
-  }
 }
\ No newline at end of file
index 1c93457977aee3cd6277077ca4b82128524ba6a3..d123a172918e45c723c126a684dc710b2c031a69 100644 (file)
@@ -17,6 +17,10 @@ public class SemanticCheck {
   
   boolean checkAll;
 
+  public boolean hasLayout(ClassDescriptor cd) {
+    return completed.get(cd)!=null&&completed.get(cd)==INIT;
+  }
+
   public SemanticCheck(State state, TypeUtil tu) {
     this(state, tu, true);
   }
@@ -44,16 +48,16 @@ public class SemanticCheck {
     return cd;
   }
 
-  private void checkClass(ClassDescriptor cd) {
+  public void checkClass(ClassDescriptor cd) {
     checkClass(cd, INIT);
   }
 
-  private void checkClass(ClassDescriptor cd, int fullcheck) {
+  public void checkClass(ClassDescriptor cd, int fullcheck) {
     if (!completed.containsKey(cd)||completed.get(cd)<fullcheck) {
       int oldstatus=completed.containsKey(cd)?completed.get(cd):0;
       completed.put(cd, fullcheck);
       
-      if (fullcheck>=REFERENCE&&oldstatus<REFERENCE) {
+      if (fullcheck>=REFERENCE&&oldstatus<INIT) {
        //Set superclass link up
        if (cd.getSuper()!=null) {
          cd.setSuper(getClass(cd, cd.getSuper(), fullcheck));
@@ -62,9 +66,11 @@ public class SemanticCheck {
          }
          // Link together Field, Method, and Flag tables so classes
          // inherit these from their superclasses
-         cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
-         cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
-         cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
+         if (oldstatus<REFERENCE) {
+           cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
+           cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
+           cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
+         }
        }
        // Link together Field, Method tables do classes inherit these from 
        // their ancestor interfaces
@@ -74,9 +80,11 @@ public class SemanticCheck {
          if(!superif.isInterface()) {
            throw new Error("Error! Class " + cd.getSymbol() + " implements non-interface " + superif.getSymbol());
          }
-         cd.addSuperInterfaces(superif);
-         cd.getFieldTable().addParentIF(superif.getFieldTable());
-         cd.getMethodTable().addParentIF(superif.getMethodTable());
+         if (oldstatus<REFERENCE) {
+           cd.addSuperInterfaces(superif);
+           cd.getFieldTable().addParentIF(superif.getFieldTable());
+           cd.getMethodTable().addParentIF(superif.getMethodTable());
+         }
        }
       }
       if (oldstatus<INIT&&fullcheck>=INIT) {
@@ -1077,6 +1085,7 @@ public class SemanticCheck {
     if (!typetolookin.isArray()) {
       // Array's don't need constructor calls
       ClassDescriptor classtolookin = typetolookin.getClassDesc();
+      checkClass(classtolookin, INIT);
 
       Set methoddescriptorset = classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
       MethodDescriptor bestmd = null;
@@ -1231,6 +1240,7 @@ public class SemanticCheck {
     if (!typetolookin.isClass())
       throw new Error("Error with method call to "+min.getMethodName());
     ClassDescriptor classtolookin=typetolookin.getClassDesc();
+    checkClass(classtolookin, INIT);
     //System.out.println("Method name="+min.getMethodName());
 
     Set methoddescriptorset=classtolookin.getMethodTable().getSet(min.getMethodName());
index 2b8f6968d8d33f35d7185604c68ab5cc87facebd..37a243c930683eb119761f9a00441ee9f0b70de6 100644 (file)
@@ -416,6 +416,7 @@ public class Main {
 
     TypeUtil tu;
     BuildFlat bf;
+    JavaBuilder jb=null;
 
     if (true) {
       BuildIR bir=new BuildIR(state);
@@ -441,7 +442,7 @@ public class Main {
       bf.buildFlat();
       State.logEvent("Done Building Flat");
     } else {
-      JavaBuilder jb=new JavaBuilder(state);
+      jb=new JavaBuilder(state);
       jb.build();
       tu=jb.getTypeUtil();
       bf=jb.getBuildFlat();
@@ -464,7 +465,7 @@ public class Main {
       }
     }
 
-    CallGraph callgraph=state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu);
+    CallGraph callgraph=jb!=null?jb:(state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu));
     
     // SSJava
     if(state.SSJAVA){
@@ -489,6 +490,8 @@ public class Main {
           /* Classify parameters */
           MethodDescriptor md=(MethodDescriptor)methodit.next();
           FlatMethod fm=state.getMethodFlat(md);
+         if (fm==null)
+           continue;
          cp.optimize(fm);
          dc.optimize(fm);
          if (!state.NOLOOP)
@@ -651,7 +654,7 @@ public class Main {
         if( state.OOOJAVA ) {
           bc=new BuildOoOJavaCode(state, bf.getMap(), tu, sa, oooa, callgraph);
         } else {
-          bc=new BuildCode(state, bf.getMap(), tu, sa, callgraph);
+          bc=new BuildCode(state, bf.getMap(), tu, sa, callgraph, jb);
         }
       }