Add support for volatile keyword in mgc version. For Tilera, as we execute a process...
authorjzhou <jzhou>
Tue, 2 Nov 2010 22:30:03 +0000 (22:30 +0000)
committerjzhou <jzhou>
Tue, 2 Nov 2010 22:30:03 +0000 (22:30 +0000)
Robust/src/IR/ClassDescriptor.java
Robust/src/IR/FieldDescriptor.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/Modifiers.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Parse/java14.cup
Robust/src/Tests/EnumTest.java [new file with mode: 0644]
Robust/src/Tests/VolatileTest.java [new file with mode: 0644]

index 8e00b5bf7f9fc375003dbfb9113cb9522d28f50f..98bb261ce656b976da67897e317c08d9a4809bd0 100644 (file)
@@ -26,9 +26,17 @@ public class ClassDescriptor extends Descriptor {
   
   // for inner classes
   boolean isInnerClass=false;
+  
+  // inner classes/enum can have these
   String surroundingclass=null;
   ClassDescriptor surroudingdesc=null;
   SymbolTable innerdescs;
+  
+  // for enum type
+  boolean isEnum = false;
+  SymbolTable enumdescs;
+  HashMap<String, Integer> enumConstantTbl;
+  int enumconstantid = 0;
 
   public ClassDescriptor(String classname, boolean isInterface) {
     this("", classname, isInterface);
@@ -50,6 +58,7 @@ public class ClassDescriptor extends Descriptor {
     superinterfaces = new Vector<String>();
     superIFdesc = new SymbolTable();
     this.innerdescs = new SymbolTable();
+    this.enumdescs = new SymbolTable();
   }
 
   public int getId() {
@@ -141,6 +150,28 @@ public class ClassDescriptor extends Descriptor {
     }
     if (printcr)
       st+="\n";
+    
+    for(Iterator it=this.getEnum(); it.hasNext();) {
+      ClassDescriptor icd = (ClassDescriptor)it.next();
+      st += icd.getModifier().toString() + " enum " + icd.getSymbol() + " {\n  ";
+      Set keys = icd.getEnumConstantTbl().keySet();
+      String[] econstants = new String[keys.size()];
+      Iterator it_keys = keys.iterator();
+      while(it_keys.hasNext()) {
+        String key = (String)it_keys.next();
+        econstants[icd.getEnumConstant(key)] = key;
+      }
+      for(int i = 0; i < econstants.length; i++) {
+        st += econstants[i];
+        if(i < econstants.length-1) {
+          st += ", ";
+        }
+      }
+      st+="\n}\n";
+      printcr=true;
+    }
+    if (printcr)
+      st+="\n";
 
     for(Iterator it=getMethods(); it.hasNext();) {
       MethodDescriptor md=(MethodDescriptor)it.next();
@@ -168,7 +199,7 @@ public class ClassDescriptor extends Descriptor {
       throw new Error(fd.getSymbol()+" already defined");
     fields.add(fd);
     fieldvec.add(fd);
-    if(fd.isStatic()) {
+    if((fd.isStatic()) || (fd.isVolatile())) {
       this.incStaticFields();
     }
   }
@@ -273,19 +304,51 @@ public class ClassDescriptor extends Descriptor {
     return this.innerdescs;
   }
   
-  /*public String getSymbol() {
-    if(this.isInnerClass) {
-      return this.surroudingdesc.getSymbol() + "." + name;
+  public void setAsEnum() {
+    this.isEnum = true;
+  }
+  
+  public boolean isEnum() {
+    return this.isEnum;
+  }
+  
+  public void addEnum(ClassDescriptor icd) {
+    this.enumdescs.add(icd);
+  }
+  
+  public Iterator getEnum() {
+    return this.enumdescs.getDescriptorsIterator();
+  }
+
+  public SymbolTable getEnumTable() {
+    return this.enumdescs;
+  }
+  
+  public void addEnumConstant(String econstant) {
+    if(this.enumConstantTbl == null) {
+      this.enumConstantTbl = new HashMap<String, Integer>();
+    }
+    if(this.enumConstantTbl.containsKey(econstant)) {
+      return;
     } else {
-      return name;
+      this.enumConstantTbl.put(econstant, this.enumconstantid++);
     }
+    return;
   }
-
-  public String getSafeSymbol() {
-    if(this.isInnerClass) {
-      return this.surroudingdesc.getSafeSymbol()+ "." + safename;
+  
+  public int getEnumConstant(String econstant) {
+    if(this.enumConstantTbl.containsKey(econstant)) {
+      return this.enumConstantTbl.get(econstant).intValue();
     } else {
-      return safename;
+      return -1;
     }
-  }*/
+  }
+  
+  public HashMap<String, Integer> getEnumConstantTbl() {
+    return this.enumConstantTbl;
+  }
+  
+  public Modifiers getModifier() {
+    return this.modifiers;
+  }
 }
index 42951328e63dc2232340be5856540a18b6bbd8e1..ecd6777a7a84ec7a1163cc98396950ae8f9d1991 100644 (file)
@@ -33,6 +33,10 @@ public class FieldDescriptor extends Descriptor {
     return modifier.isStatic();
   }
   
+  public boolean isVolatile() {
+    return modifier.isVolatile();
+  }
+  
   public boolean isGlobal() {
     return isglobal;
   }
index 0d713f23737f069794f9325bcb370113e6e26116..ee4560cf140b7afe9c62489392a5d4f6830c6af0 100644 (file)
@@ -1623,7 +1623,16 @@ public class BuildCode {
       else if ((state.MGC) && (fd.isStatic())) {
         // TODO add version for normal Java later
         // static field
-        globaldefout.println("  "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+        if(fd.isVolatile()) {
+          globaldefout.println("  volatile "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+        } else {
+          globaldefout.println("  "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+        }
+        classdefout.println("  "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
+      } else if ((state.MGC) && (fd.isVolatile())) {
+        // TODO add version for normal Java later
+        // static field
+        globaldefout.println("  volatile "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
         classdefout.println("  "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
       } else
        classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
@@ -2171,8 +2180,8 @@ public class BuildCode {
 
       for(int i=0; i<fields.size(); i++) {
         FieldDescriptor fd=(FieldDescriptor)fields.get(i);
-        if(fd.isStatic()) {
-          // static field
+        if((fd.isStatic()) || (fd.isVolatile())) {
+          // static/volatile field
           output.println(generateTemp(fm,fm.getParameter(0),lb)+"->"+fd.getSafeSymbol()+"=&(global_defs_p->"+cn.getSafeSymbol()+fd.getSafeSymbol()+");");
         }
       }
@@ -5054,7 +5063,7 @@ public class BuildCode {
 // DEBUG       } 
       if(state.MGC) {
         // TODO add version for normal Java later
-      if(ffn.getField().isStatic()) {
+      if((ffn.getField().isStatic()) || (ffn.getField().isVolatile())) {
         // static field
         if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
           // is a static block or is invoked in some static block
@@ -5200,7 +5209,7 @@ public class BuildCode {
 // DEBUG   } 
       if(state.MGC) {
         // TODO add version for normal Java later
-      if(fsfn.getField().isStatic()) {
+      if((fsfn.getField().isStatic()) || (fsfn.getField().isVolatile())) {
         // static field
         if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
           // is a static block or is invoked in some static block
index cf43c80c96a53861a7aaf83b5d14a683a5f99304..2e9f1aa247de83f80bcc483ff0b19388e2ad855e 100644 (file)
@@ -55,7 +55,7 @@ public class BuildIR {
          if (toanalyze!=null)
            toanalyze.add(cn);
          state.addClass(cn);
-      // for inner classes
+      // for inner classes/enum
       if(state.MGC) {
         // TODO add version for normal Java later
         HashSet tovisit = new HashSet();
@@ -77,6 +77,24 @@ public class BuildIR {
           while(it_ics.hasNext()) {
             tovisit.add(it_ics.next());
           }
+          
+          Iterator it_ienums = cd.getEnum();
+          while(it_ienums.hasNext()) {
+            ClassDescriptor iecd = (ClassDescriptor)it_ienums.next();
+            if(toanalyze != null) {
+              toanalyze.add(iecd);
+            }
+            state.addClass(iecd);
+          }
+        }
+        
+        Iterator it_enums = cn.getEnum();
+        while(it_enums.hasNext()) {
+          ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
+          if(toanalyze != null) {
+            toanalyze.add(ecd);
+          }
+          state.addClass(ecd);
         }
       }
        } else if (isNode(type_pn,"task_declaration")) {
@@ -90,6 +108,25 @@ public class BuildIR {
       if (toanalyze!=null)
         toanalyze.add(cn);
       state.addClass(cn);
+      
+      // for enum
+      if(state.MGC) {
+        // TODO add version for normal Java later        
+        Iterator it_enums = cn.getEnum();
+        while(it_enums.hasNext()) {
+          ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
+          if(toanalyze != null) {
+            toanalyze.add(ecd);
+          }
+          state.addClass(ecd);
+        }
+      }
+    } else if ((state.MGC) && isNode(type_pn,"enum_declaration")) {
+      // TODO add version for normal Java later
+      ClassDescriptor cn = parseEnumDecl(null, type_pn);
+      if (toanalyze!=null)
+        toanalyze.add(cn);
+      state.addClass(cn);
     } else {
          throw new Error(type_pn.getLabel());
        }
@@ -97,6 +134,40 @@ public class BuildIR {
     }
   }
   
+  private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
+    ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+    ecd.setAsEnum();
+    if(cn != null) {
+      ecd.setSurroundingClass(cn.getSymbol());
+      ecd.setSurrounding(cn);
+    }
+    cn.addEnum(ecd);
+    if (!(ecd.getSymbol().equals(TypeUtil.ObjectClass)||
+        ecd.getSymbol().equals(TypeUtil.TagClass))) {
+      ecd.setSuper(TypeUtil.ObjectClass);
+    }
+    ecd.setModifiers(parseModifiersList(pn.getChild("modifiers")));
+    parseEnumBody(ecd, pn.getChild("enumbody"));
+    return ecd;
+  }
+  
+  private void parseEnumBody(ClassDescriptor cn, ParseNode pn) {
+    ParseNode decls=pn.getChild("enum_constants_list");
+    if (decls!=null) {
+      ParseNodeVector pnv=decls.getChildren();
+      for(int i=0; i<pnv.size(); i++) {
+        ParseNode decl=pnv.elementAt(i);
+        if (isNode(decl,"enum_constant")) {
+          parseEnumConstant(cn,decl);
+        } else throw new Error();
+      }
+    }
+  }
+  
+  private void parseEnumConstant(ClassDescriptor cn, ParseNode pn) {
+    cn.addEnumConstant(pn.getChild("name").getTerminal());
+  }
+  
   public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
     //cn.setAsInterface();
@@ -404,6 +475,16 @@ public class BuildIR {
         throw new Error("Error: inner class in Class " + cn.getSymbol() + " is not supported yet");
       }
     }
+    ParseNode enumnode=pn.getChild("enum_declaration");
+    if (enumnode!=null) {
+      if(state.MGC){
+        parseEnumDecl(cn,enumnode);
+        return;
+      } else {
+        // TODO add version for noraml Java later
+        throw new Error("Error: enumerated type in Class " + cn.getSymbol() + " is not supported yet");
+      }
+    }
     ParseNode flagnode=pn.getChild("flag");
     if (flagnode!=null) {
       parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
@@ -1099,6 +1180,8 @@ public class BuildIR {
          m.addModifier(Modifiers.ATOMIC);
     else if (isNode(modn,"abstract"))
       m.addModifier(Modifiers.ABSTRACT);
+    else if (isNode(modn,"volatile"))
+      m.addModifier(Modifiers.VOLATILE);
        else throw new Error("Unrecognized Modifier");
       }
     }
index 441d2b3a17faf9353823a37d35062e75af29edb2..709d46a9b27fc69c6555117b7b9f7fa1567cd663 100644 (file)
@@ -10,7 +10,7 @@ public class Modifiers {
   public static final int NATIVE=64;
   public static final int SYNCHRONIZED=128;
 //     TRANSIENT=256
-//     VOLATILE=512
+  public static final int VOLATILE=512;
 //     STRICTFP=1024
   public static final int ATOMIC=2048;
 
@@ -54,6 +54,10 @@ public class Modifiers {
   public boolean isFinal() {
     return ((value&FINAL)!=0);
   }
+  
+  public boolean isVolatile() {
+    return ((value&VOLATILE)!= 0);
+  }
 
   public String toString() {
     String st="";
@@ -75,6 +79,8 @@ public class Modifiers {
       st+="atomic ";
     if ((value&ABSTRACT)!=0)
       st+="abstract ";
+    if((value&VOLATILE)!=0)
+      st += "volatile ";
     return st;
   }
 }
index 7fa1899c85717ec67cfc243cbc198fe406218843..ba82bb1ba9f47dbfe45c7005e9e4294061c80c40 100644 (file)
@@ -611,7 +611,7 @@ public class SemanticCheck {
           cd = ((MethodDescriptor)md).getClassDesc();
           SymbolTable fieldtbl = cd.getFieldTable();
           FieldDescriptor fd=(FieldDescriptor)fieldtbl.get(varname);
-          if((fd == null) || (!fd.isStatic())){
+          if((fd == null) || (!fd.isStatic()) || (!fd.isVolatile())){
             // no such field in the class or it is not a static field
             throw new Error("Name "+varname+" should not be used in static block: "+md);
           } else {
index 630ca714694532fc59d28ac28665dec4f23cd018..9ee773bb216b25fa488a01bf17412fd59712e533 100644 (file)
@@ -274,6 +274,12 @@ terminal SESE;
 terminal RBLOCK;
 non terminal ParseNode sese_statement;
 
+// mgc
+// JSR-201) Enum Declaration
+non terminal ParseNode enum_declaration;
+non terminal ParseNode enum_body, enum_constants_opt, enum_constants, enum_constant;
+//non terminal ParseNode enum_arguments_opt, enum_body_declarations_opt;
+
 
 start with goal;
 
@@ -685,6 +691,10 @@ type_declaration ::=
                {:
                        RESULT=cd;
                :}
+       |       enum_declaration:ed
+           {:
+               RESULT=ed;
+           :}
        |       task_declaration:td 
                {:
                        RESULT=td;
@@ -722,9 +732,10 @@ modifier ::=
        FINAL {: RESULT=new ParseNode("final"); :}|
        NATIVE {: RESULT=new ParseNode("native"); :} |
        SYNCHRONIZED {: RESULT=new ParseNode("synchronized"); :} |
-       ATOMIC {: RESULT=new ParseNode("atomic"); :}
+       ATOMIC {: RESULT=new ParseNode("atomic"); :} |
+       VOLATILE {: RESULT=new ParseNode("volatile"); :}
 //     TRANSIENT | 
-//     VOLATILE |
+
 //     STRICTFP // note that semantic analysis must check that the
                         // context of the modifier allows strictfp.
        ;
@@ -830,11 +841,65 @@ class_member_declaration ::=
        pn.addChild("classbody").addChild(body);
        RESULT=pn;
        :}
+       |       enum_declaration:ed
+       {:
+       RESULT=ed; 
+       :}
 //    |       interface_declaration:interfaced {: 
 //     RESULT=(new ParseNode("interface")).addChild(interfaced).getRoot(); 
 //     :}
        |       SEMICOLON       {: RESULT=new ParseNode("empty"); :}
        ;
+       
+// mgc
+// JSR-201) Enum Declaration
+enum_declaration ::=
+               modifiers_opt:mo ENUM IDENTIFIER:id /*interfaces_opt:io*/ enum_body:body
+               {:
+                       ParseNode pn=new ParseNode("enum_declaration");
+                       pn.addChild("modifiers").addChild(mo);
+                       pn.addChild("name").addChild(id);
+                       //pn.addChild("superIF").addChild(ifo);
+                       pn.addChild("enumbody").addChild(body);
+                       RESULT=pn;
+               :}
+       ;
+enum_body ::=
+               LBRACE enum_constants_opt:eco /*enum_body_declarations_opt:ebdo*/ RBRACE
+               {: RESULT=eco; :}
+       ;
+enum_constants_opt ::=
+   {: RESULT=new ParseNode("empty"); :}
+       |       enum_constants:ecs
+       {: RESULT=ecs; :}
+       ;
+enum_constants ::=
+               enum_constant:ec {: 
+               ParseNode pn=new ParseNode("enum_constants_list");
+               pn.addChild(ec);
+               RESULT=pn;
+       :}
+       |       enum_constants:ecs COMMA enum_constant:ec {:
+           ecs.addChild(ec);
+           RESULT=ecs;
+       :}
+       ;
+enum_constant ::=
+               IDENTIFIER:id /*enum_arguments_opt*/
+               {: 
+                   ParseNode pn=new ParseNode("enum_constant");
+                   pn.addChild("name").addChild(id);
+                   RESULT=pn; 
+               :}
+//     |       IDENTIFIER enum_arguments_opt class_body
+       ;
+//enum_arguments_opt ::=
+//     |       LPAREN argument_list_opt RPAREN
+//     ;
+//enum_body_declarations_opt ::=
+//     |       SEMICOLON class_body_declarations_opt:cbdo
+//     ;
+
 
 //Failure aware computation
 flag_declaration ::= 
@@ -1126,6 +1191,9 @@ interface_member_declaration ::=
        |       abstract_method_declaration:method {:
        RESULT=(new ParseNode("method")).addChild(method).getRoot(); 
        :}
+          |    enum_declaration:ed {:
+          RESULT=(new ParseNode("enum_declaration")).addChild(ed).getRoot();
+          :}
 //       |       class_declaration:class 
 //       |       interface_declaration:interface 
        |       SEMICOLON {: 
@@ -1207,6 +1275,9 @@ block_statement ::=
        |       statement:statement {: 
                RESULT=statement;
        :}
+//     |       enum_declaration:ed {:
+//             RESULT=ed;
+//     :}
 //     |       class_declaration
 //     |       interface_declaration
        ;
@@ -2059,6 +2130,8 @@ expression_opt ::=
 expression ::= assignment_expression:exp {: 
                RESULT=exp; :}
        ;
+// note that this constraint must be enforced during semantic checking
+// 'constant_expression' should include enumerated constants.
 //constant_expression ::=
 //             expression
 //     ;
diff --git a/Robust/src/Tests/EnumTest.java b/Robust/src/Tests/EnumTest.java
new file mode 100644 (file)
index 0000000..c377727
--- /dev/null
@@ -0,0 +1,15 @@
+public enum Spiciness {
+  NOT, MILD, MEDIUM, HOT, FLAMING
+} ///:~
+
+public class EnumTest {
+  
+  public EnumTest(){}
+  
+  public static void main(String[] args) {
+    Spiciness howHot = Spiciness.MEDIUM;
+    System.out.println(howHot);
+  }
+} /* Output:
+MEDIUM
+*///:~
diff --git a/Robust/src/Tests/VolatileTest.java b/Robust/src/Tests/VolatileTest.java
new file mode 100644 (file)
index 0000000..4eb0c7b
--- /dev/null
@@ -0,0 +1,31 @@
+public class VolatileTest  extends Thread {
+  volatile int num;   
+  String name;
+  
+  {
+    num = 0;
+  }
+  
+  public VolatileTest(String name) {
+    this.name = name;
+  }
+
+  public void run(){
+    if(name.equals("Thread1")){  
+      num=10;  
+    }  
+    else{  
+      System.out.println("value of num is :"+num);  
+    }     
+  }  
+
+  public static void main(String args[]){  
+    Thread t1 = new VolatileTest("Thread1");   
+    t1.start();  
+
+    Thread.sleep(1000);  
+
+    Thread t2 = new VolatileTest("Thread2");   
+    t2.start();  
+  }  
+}  
\ No newline at end of file