add more comments
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index e33fc83c81b055f1cef92ace49e018aca3c5fbdd..56fa8c20a834884300580ce9d53f8311c9aceb6f 100644 (file)
@@ -2,9 +2,14 @@ package IR.Flat;
 import IR.Tree.FlagExpressionNode;
 import IR.Tree.DNFFlag;
 import IR.Tree.DNFFlagAtom;
+import IR.Tree.TagExpressionList;
 import IR.*;
 import java.util.*;
 import java.io.*;
+import Util.Relation;
+import Analysis.TaskStateAnalysis.FlagState;
+import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
+import Analysis.TaskStateAnalysis.Predicate;
 
 public class BuildCode {
     State state;
@@ -22,9 +27,10 @@ public class BuildCode {
     Virtual virtualcalls;
     TypeUtil typeutil;
     private int maxtaskparams=0;
+    private int maxcount=0;
     ClassDescriptor[] cdarray;
     TypeDescriptor[] arraytable;
-
+   
     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
        state=st;
        this.temptovar=temptovar;
@@ -50,27 +56,25 @@ public class BuildCode {
        PrintWriter outvirtual=null;
        PrintWriter outtask=null;
        PrintWriter outtaskdefs=null;
+       PrintWriter outoptionalarrays=null;
+       PrintWriter optionalheaders=null;
 
        try {
-           OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
-           outstructs=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"methodheaders.h");
-           outmethodheader=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"classdefs.h");
-           outclassdefs=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"methods.c");
-           outmethod=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"virtualtable.h");
-           outvirtual=new java.io.PrintWriter(str, true);
+           outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
+           outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
+           outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
+           outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
+           outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
            if (state.TASK) {
-               str=new FileOutputStream(PREFIX+"task.h");
-               outtask=new java.io.PrintWriter(str, true);
-               str=new FileOutputStream(PREFIX+"taskdefs.c");
-               outtaskdefs=new java.io.PrintWriter(str, true);
+               outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
+               outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
+               if (state.OPTIONAL){
+                   outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
+                   optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
+               } 
            }
            if (state.structfile!=null) {
-               str=new FileOutputStream(PREFIX+state.structfile+".struct");
-               outrepairstructs=new java.io.PrintWriter(str, true);
+               outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -81,73 +85,32 @@ public class BuildCode {
        buildVirtualTables(outvirtual);
 
        /* Output includes */
-       outstructs.println("#include \"classdefs.h\"");
+       outmethodheader.println("#ifndef METHODHEADERS_H");
+       outmethodheader.println("#define METHODHEADERS_H");
        outmethodheader.println("#include \"structdefs.h\"");
 
-       /* Output types for short array and string */
-       outstructs.println("#define STRINGARRAYTYPE "+
-                          (state.getArrayNumber(
-                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
-
-       outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
-       outstructs.println("#define CHARARRAYTYPE "+
-                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
-       outstructs.println("#define NUMCLASSES "+state.numClasses());
-       if (state.TASK)
-           outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
+       /* Output Structures */
+       outputStructs(outstructs);
 
        // Output the C class declarations
        // These could mutually reference each other
-       outclassdefs.println("struct "+arraytype+";");
-
-       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
-       while(it.hasNext()) {
-           ClassDescriptor cn=(ClassDescriptor)it.next();
-           outclassdefs.println("struct "+cn.getSafeSymbol()+";");
-       }
-       outclassdefs.println("");
-       {
-           //Print out definition for array type
-           outclassdefs.println("struct "+arraytype+" {");
-           outclassdefs.println("  int type;");
-           if (state.TASK) {
-               outclassdefs.println("  int flag;");
-               outclassdefs.println("  void * flagptr;");
-           }
-           printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
-           outclassdefs.println("  int ___length___;");
-           outclassdefs.println("};\n");
+       outputClassDeclarations(outclassdefs);
 
-           if (state.TASK) {
-           //Print out definitions for task types
-               outtask.println("struct parameterdescriptor {");
-               outtask.println("int type;");
-               outtask.println("int numberterms;");
-               outtask.println("int *intarray;");
-               outtask.println("void * queue;");
-               outtask.println("};");
-
-               outtask.println("struct taskdescriptor {");
-               outtask.println("void * taskptr;");
-               outtask.println("int numParameters;");
-               outtask.println("struct parameterdescriptor **descriptorarray;");
-               outtask.println("char * name;");
-               outtask.println("};");
-               outtask.println("extern struct taskdescriptor * taskarray[];");
-               outtask.println("extern numtasks;");
-           }
-       }
+       /* Outputs task structures if this is a task program */
+       if (state.TASK)
+           outputTaskTypes(outtask);
 
        // Output function prototypes and structures for parameters
-       it=state.getClassSymbolTable().getDescriptorsIterator();
+       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
        while(it.hasNext()) {
            ClassDescriptor cn=(ClassDescriptor)it.next();
            generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
        }
-
+       outclassdefs.close();
 
        if (state.TASK) {
            /* Map flags to integers */
+           /* The runtime keeps track of flags using these integers */
            it=state.getClassSymbolTable().getDescriptorsIterator();
            while(it.hasNext()) {
                ClassDescriptor cn=(ClassDescriptor)it.next();
@@ -157,26 +120,129 @@ public class BuildCode {
            generateTaskStructs(outstructs, outmethodheader);
        }
 
+       /* Build the actual methods */
+       outputMethods(outmethod);
+
+       if (state.TASK) {
+           outputTaskCode(outtaskdefs, outmethod);
+           outtaskdefs.close();
+       } else if (state.main!=null) {
+           /* Generate main method */
+           outputMainMethod(outmethod);
+       }
+       outmethodheader.println("#endif");
        outmethodheader.close();
+       outmethod.close();
+       
+       if (state.TASK)
+           outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
+       outstructs.println("#endif");
+       outstructs.close();
+       
+       /* Generate information for task with optional parameters */
+       if (state.TASK&&state.OPTIONAL){
+           generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
+           outoptionalarrays.close();
+       } 
 
-       /* Build the actual methods */
+       /* Output structure definitions for repair tool */
+       if (state.structfile!=null) {
+           buildRepairStructs(outrepairstructs);
+           outrepairstructs.close();
+       }
+    }
+
+    private void outputMainMethod(PrintWriter outmethod) {
+       outmethod.println("int main(int argc, const char *argv[]) {");
+       outmethod.println("  int i;");
+       if (GENERATEPRECISEGC) {
+           outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
+       } else {
+           outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
+       }
+       if (state.THREAD) {
+           outmethod.println("initializethreads();");
+       }
+       outmethod.println("  for(i=1;i<argc;i++) {");
+       outmethod.println("    int length=strlen(argv[i]);");
+       if (GENERATEPRECISEGC) {
+           outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
+       } else {
+           outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
+       }
+       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
+       outmethod.println("  }");
+       
+       
+       MethodDescriptor md=typeutil.getMain();
+       ClassDescriptor cd=typeutil.getMainClass();
+       
+       outmethod.println("   {");
+       if (GENERATEPRECISEGC) {
+           outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
+           outmethod.println("1, NULL,"+"stringarray};");
+           outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
+       } else
+           outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
+       outmethod.println("   }");
+       
+       if (state.THREAD) {
+           outmethod.println("pthread_mutex_lock(&gclistlock);");
+           outmethod.println("threadcount--;");
+           outmethod.println("pthread_cond_signal(&gccond);");
+           outmethod.println("pthread_mutex_unlock(&gclistlock);");
+           outmethod.println("pthread_exit(NULL);");
+       }
+       outmethod.println("}");
+    }
+
+    private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
+       /* Compile task based program */
+       outtaskdefs.println("#include \"task.h\"");
+       outtaskdefs.println("#include \"methodheaders.h\"");
+       Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+       while(taskit.hasNext()) {
+           TaskDescriptor td=(TaskDescriptor)taskit.next();
+           FlatMethod fm=state.getMethodFlat(td);
+           generateFlatMethod(fm, outmethod);
+           generateTaskDescriptor(outtaskdefs, fm, td);
+       }
+       
+       //Output task descriptors
+       taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+       outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
+       boolean first=true;
+       while(taskit.hasNext()) {
+           TaskDescriptor td=(TaskDescriptor)taskit.next();
+           if (first)
+               first=false;
+           else
+               outtaskdefs.println(",");
+           outtaskdefs.print("&task_"+td.getSafeSymbol());
+       }
+       outtaskdefs.println("};");
+
+       outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
+    }
+
+    private void outputMethods(PrintWriter outmethod) {
        outmethod.println("#include \"methodheaders.h\"");
        outmethod.println("#include \"virtualtable.h\"");
        outmethod.println("#include <runtime.h>");
+       if (state.THREAD)
+           outmethod.println("#include <thread.h>");
        if (state.main!=null) {
            outmethod.println("#include <string.h>");       
        }
-
        if (state.CONSCHECK) {
            outmethod.println("#include \"checkers.h\"");
        }
-       outclassdefs.println("extern int classsize[];");
-       outclassdefs.println("extern int hasflags[];");
-       outclassdefs.println("extern int * pointerarray[];");
-
        //Store the sizes of classes & array elements
        generateSizeArray(outmethod);
        
+       //Store table of supertypes
+       generateSuperTypeTable(outmethod);
+
        //Store the layout of classes
        generateLayoutStructs(outmethod);
 
@@ -193,82 +259,102 @@ public class BuildCode {
                    generateFlatMethod(fm,outmethod);
            }
        }
+    }
 
-       if (state.TASK) {
-           /* Compile task based program */
-           outtaskdefs.println("#include \"task.h\"");
-           outtaskdefs.println("#include \"methodheaders.h\"");
-           Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
-           while(taskit.hasNext()) {
-               TaskDescriptor td=(TaskDescriptor)taskit.next();
-               FlatMethod fm=state.getMethodFlat(td);
-               generateFlatMethod(fm, outmethod);
-               generateTaskDescriptor(outtaskdefs, td);
-           }
+    private void outputStructs(PrintWriter outstructs) {
+       outstructs.println("#ifndef STRUCTDEFS_H");
+       outstructs.println("#define STRUCTDEFS_H");
+       outstructs.println("#include \"classdefs.h\"");
 
-           {
-               //Output task descriptors
-               taskit=state.getTaskSymbolTable().getDescriptorsIterator();
-               outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
-               boolean first=true;
-               while(taskit.hasNext()) {
-                   TaskDescriptor td=(TaskDescriptor)taskit.next();
-                   if (first)
-                       first=false;
-                   else
-                       outtaskdefs.println(",");
-                   outtaskdefs.print("&task_"+td.getSafeSymbol());
-               }
-               outtaskdefs.println("};");
-           }
+       /* Output #defines that the runtime uses to determine type
+        * numbers for various objects it needs */
 
-           outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
+       outstructs.println("#define STRINGARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
 
-       } else if (state.main!=null) {
-           /* Generate main method */
-           outmethod.println("int main(int argc, const char *argv[]) {");
-           outmethod.println("int i;");
-           outmethod.println("struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
-           outmethod.println("for(i=1;i<argc;i++) {");
-           outmethod.println("int length=strlen(argv[i]);");
-           outmethod.println("struct ___String___ *newstring=NewString(argv[i],length);");
-           outmethod.println("((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
-           outmethod.println("}");
-
-
-           ClassDescriptor cd=typeutil.getClass(state.main);
-           Set mainset=cd.getMethodTable().getSet("main");
-           for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
-               MethodDescriptor md=(MethodDescriptor)mainit.next();
-               if (md.numParameters()!=1)
-                   continue;
-               if (md.getParameter(0).getType().getArrayCount()!=1)
-                   continue;
-               if (!md.getParameter(0).getType().getSymbol().equals("String"))
-                   continue;
-
-               if (!md.getModifiers().isStatic())
-                   throw new Error("Error: Non static main");
-               outmethod.println("   "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
-               break;
-           }
-           outmethod.println("}");
-       }
-       if (state.TASK)
-           outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
+       outstructs.println("#define OBJECTARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
 
 
-       /* Output structure definitions for repair tool */
-       if (state.structfile!=null) {
-           buildRepairStructs(outrepairstructs);
-           outrepairstructs.close();
+       outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
+       outstructs.println("#define CHARARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
+
+       outstructs.println("#define BYTEARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
+
+       outstructs.println("#define BYTEARRAYARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
+       
+       outstructs.println("#define NUMCLASSES "+state.numClasses());
+       if (state.TASK) {
+           outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
+           outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
+           outstructs.println("#define TAGARRAYTYPE "+
+                              (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
        }
+    }
 
-       outstructs.close();
-       outmethod.close();
+    private void outputClassDeclarations(PrintWriter outclassdefs) {
+       if (state.THREAD)
+           outclassdefs.println("#include <pthread.h>");
+       outclassdefs.println("struct "+arraytype+";");
+       /* Start by declaring all structs */
+       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
+       while(it.hasNext()) {
+           ClassDescriptor cn=(ClassDescriptor)it.next();
+           outclassdefs.println("struct "+cn.getSafeSymbol()+";");
+       }
+       outclassdefs.println("");
+       //Print out definition for array type
+       outclassdefs.println("struct "+arraytype+" {");
+       outclassdefs.println("  int type;");
+       if (state.THREAD) {
+           outclassdefs.println("  pthread_t tid;");
+           outclassdefs.println("  void * lockentry;");
+           outclassdefs.println("  int lockcount;");
+       }
+       if (state.TASK) {
+           outclassdefs.println("  int flag;");
+           outclassdefs.println("  void * flagptr;");
+           if(state.OPTIONAL) outclassdefs.println("  int failedstatus;");
+       }
+       printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
+       
+       outclassdefs.println("  int ___length___;");
+       outclassdefs.println("};\n");
+       outclassdefs.println("extern int classsize[];");
+       outclassdefs.println("extern int hasflags[];");
+       outclassdefs.println("extern int * pointerarray[];");
+       outclassdefs.println("extern int supertypes[];");
     }
 
-    private int maxcount=0;
+    private void outputTaskTypes(PrintWriter outtask) {
+       //Print out definitions for task types
+       outtask.println("#ifndef _TASK_H");
+       outtask.println("#define _TASK_H");
+       outtask.println("struct parameterdescriptor {");
+       outtask.println("int type;");
+       outtask.println("int numberterms;");
+       outtask.println("int *intarray;");
+       outtask.println("void * queue;");
+       outtask.println("int numbertags;");
+       outtask.println("int *tagarray;");
+       outtask.println("};");
+       
+       outtask.println("struct taskdescriptor {");
+       outtask.println("void * taskptr;");
+       outtask.println("int numParameters;");
+       outtask.println("int numTotal;");
+       outtask.println("struct parameterdescriptor **descriptorarray;");
+       outtask.println("char * name;");
+       outtask.println("};");
+       outtask.println("extern struct taskdescriptor * taskarray[];");
+       outtask.println("extern numtasks;");
+       outtask.println("#endif");
+    }
 
     private void buildRepairStructs(PrintWriter outrepairstructs) {
        Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
@@ -316,46 +402,81 @@ public class BuildCode {
                output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
            } else if (fd.getType().isClass())
                output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
+           else if (fd.getType().isFloat())
+               output.println("  int "+fd.getSymbol()+"; /* really float */");
            else 
                output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
        }
     }
 
     /** This method outputs TaskDescriptor information */
-    void generateTaskDescriptor(PrintWriter output, TaskDescriptor task) {
+    void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
        for (int i=0;i<task.numParameters();i++) {
            VarDescriptor param_var=task.getParameter(i);
            TypeDescriptor param_type=task.getParamType(i);
            FlagExpressionNode param_flag=task.getFlag(param_var);
-           DNFFlag dflag=param_flag.getDNF();
-           
-           Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
-                       
-           output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
-           for(int j=0;j<dflag.size();j++) {
-               if (j!=0)
-                   output.println(",");
-               Vector term=dflag.get(j);
-               int andmask=0;
-               int checkmask=0;
-               for(int k=0;k<term.size();k++) {
-                   DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
-                   FlagDescriptor fd=dfa.getFlag();
-                   boolean negated=dfa.getNegated();
-                   int flagid=1<<((Integer)flags.get(fd)).intValue();
-                   andmask|=flagid;
-                   if (!negated)
-                       checkmask|=flagid;
+           TagExpressionList param_tag=task.getTag(param_var);
+
+           int dnfterms;
+           if (param_flag==null) {
+               output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
+               output.println("0x0, 0x0 };");
+               dnfterms=1;
+           } else {
+
+               DNFFlag dflag=param_flag.getDNF();
+               dnfterms=dflag.size();
+               
+               Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
+               output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
+               for(int j=0;j<dflag.size();j++) {
+                   if (j!=0)
+                       output.println(",");
+                   Vector term=dflag.get(j);
+                   int andmask=0;
+                   int checkmask=0;
+                   for(int k=0;k<term.size();k++) {
+                       DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
+                       FlagDescriptor fd=dfa.getFlag();
+                       boolean negated=dfa.getNegated();
+                       int flagid=1<<((Integer)flags.get(fd)).intValue();
+                       andmask|=flagid;
+                       if (!negated)
+                           checkmask|=flagid;
+                   }
+                   output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
                }
-               output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
+               output.println("};");
            }
+
+           output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
+           //BUG...added next line to fix, test with any task program
+           if (param_tag!=null)
+               for(int j=0;j<param_tag.numTags();j++) {
+                   if (j!=0)
+                       output.println(",");
+                   /* for each tag we need */
+                   /* which slot it is */
+                   /* what type it is */
+                   TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
+                   TempDescriptor tmp=param_tag.getTemp(j);
+                   int slot=fm.getTagInt(tmp);
+                   output.println(slot+", "+state.getTagId(tvd.getTag()));
+               }
            output.println("};");
 
            output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
            output.println("/* type */"+param_type.getClassDesc().getId()+",");
-           output.println("/* number of DNF terms */"+dflag.size()+",");
+           output.println("/* number of DNF terms */"+dnfterms+",");
            output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
-           output.println("0");
+           output.println("0,");
+           //BUG, added next line to fix and else statement...test
+           //with any task program
+           if (param_tag!=null)
+               output.println("/* number of tags */"+param_tag.numTags()+",");
+           else
+               output.println("/* number of tags */ 0,");
+           output.println("parametertag_"+i+"_"+task.getSafeSymbol());
            output.println("};");
        }
 
@@ -371,6 +492,8 @@ public class BuildCode {
        output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
        output.println("&"+task.getSafeSymbol()+",");
        output.println("/* number of parameters */" +task.numParameters() + ",");
+       int numtotal=task.numParameters()+fm.numTags();
+       output.println("/* number total parameters */" +numtotal + ",");
        output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
        output.println("\""+task.getSymbol()+"\"");
        output.println("};");
@@ -504,6 +627,14 @@ public class BuildCode {
                objectparams.addPrim(temp);
        }
 
+       for(int i=0;i<fm.numTags();i++) {
+           TempDescriptor temp=fm.getTag(i);
+           if (GENERATEPRECISEGC)
+               objectparams.addPtr(temp);
+           else
+               objectparams.addPrim(temp);
+       }
+
        TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
        if (md!=null)
            tempstable.put(md, objecttemps);
@@ -523,7 +654,14 @@ public class BuildCode {
            }
        }
     }
-    
+
+    /** This method outputs the following information about classes
+     * and arrays:
+     * (1) For classes, what are the locations of pointers.
+     * (2) For arrays, does the array contain pointers or primitives.
+     * (3) For classes, does the class contain flags.
+     */
+
     private void generateLayoutStructs(PrintWriter output) {
        Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
        while(it.hasNext()) {
@@ -586,7 +724,25 @@ public class BuildCode {
        output.println("};");
     }
 
-    /* Force consistent field ordering between inherited classes. */
+    /** Print out table to give us supertypes */
+    private void generateSuperTypeTable(PrintWriter output) {
+       output.println("int supertypes[]={");
+       boolean needcomma=false;
+       for(int i=0;i<state.numClasses();i++) {
+           ClassDescriptor cn=cdarray[i];
+           if (needcomma)
+               output.println(",");
+           needcomma=true;
+           if (cn.getSuperDesc()!=null) {
+               ClassDescriptor cdsuper=cn.getSuperDesc();
+               output.print(cdsuper.getId());
+           } else
+               output.print("-1");
+       }
+       output.println("};");
+    }
+
+    /** Force consistent field ordering between inherited classes. */
 
     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
        ClassDescriptor sp=cn.getSuperDesc();
@@ -656,9 +812,16 @@ public class BuildCode {
        /* Output class structure */
        classdefout.println("struct "+cn.getSafeSymbol()+" {");
        classdefout.println("  int type;");
+       if (state.THREAD) {
+           classdefout.println("  pthread_t tid;");
+           classdefout.println("  void * lockentry;");
+           classdefout.println("  int lockcount;");
+       }
+
        if (state.TASK) {
            classdefout.println("  int flag;");
            classdefout.println("  void * flagptr;");
+           if (state.OPTIONAL) classdefout.println("  int failedstatus;");
        }
        printClassStruct(cn, classdefout);
        classdefout.println("};\n");
@@ -677,7 +840,7 @@ public class BuildCode {
            /* Output parameter structure */
            if (GENERATEPRECISEGC) {
                output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
-               output.println("  int type;");
+               output.println("  int size;");
                output.println("  void * next;");
                for(int i=0;i<objectparams.numPointers();i++) {
                    TempDescriptor temp=objectparams.getPointer(i);
@@ -689,7 +852,7 @@ public class BuildCode {
            /* Output temp structure */
            if (GENERATEPRECISEGC) {
                output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
-               output.println("  int type;");
+               output.println("  int size;");
                output.println("  void * next;");
                for(int i=0;i<objecttemps.numPointers();i++) {
                    TempDescriptor temp=objecttemps.getPointer(i);
@@ -755,26 +918,31 @@ public class BuildCode {
            if (GENERATEPRECISEGC) {
                output.println("struct "+task.getSafeSymbol()+"_params {");
 
-               output.println("  int type;");
+               output.println("  int size;");
                output.println("  void * next;");
                for(int i=0;i<objectparams.numPointers();i++) {
                    TempDescriptor temp=objectparams.getPointer(i);
                    output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
                }
+
                output.println("};\n");
-               if (objectparams.numPointers()>maxtaskparams)
-                   maxtaskparams=objectparams.numPointers();
+               if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
+                   maxtaskparams=objectparams.numPointers()+fm.numTags();
+               }
            }
 
            /* Output temp structure */
            if (GENERATEPRECISEGC) {
                output.println("struct "+task.getSafeSymbol()+"_locals {");
-               output.println("  int type;");
+               output.println("  int size;");
                output.println("  void * next;");
                for(int i=0;i<objecttemps.numPointers();i++) {
                    TempDescriptor temp=objecttemps.getPointer(i);
                    if (temp.getType().isNull())
                        output.println("  void * "+temp.getSafeSymbol()+";");
+                   else if(temp.getType().isTag())
+                       output.println("  struct "+
+                                      (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
                    else
                        output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
                }
@@ -793,7 +961,7 @@ public class BuildCode {
        }
     }
 
-    /** Generate code for flatmethod fm. */
+    /** Generate code for FlatMethod fm. */
 
     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
        MethodDescriptor md=fm.getMethod();
@@ -803,17 +971,24 @@ public class BuildCode {
 
        ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
 
-       generateHeader(md!=null?md:task,output);
+       generateHeader(fm, md!=null?md:task,output);
+
+       TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
 
        /* Print code */
-       
        if (GENERATEPRECISEGC) {
            if (md!=null)
-               output.println("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+";");
+               output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
            else
-               output.println("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+";");
+               output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
+
+           output.print(objecttemp.numPointers()+",");
+           output.print(paramsprefix);
+           for(int j=0;j<objecttemp.numPointers();j++)
+               output.print(", NULL");
+           output.println("};");
        }
-       TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
+
        for(int i=0;i<objecttemp.numPrimitives();i++) {
            TempDescriptor td=objecttemp.getPrimitive(i);
            TypeDescriptor type=td.getType();
@@ -824,14 +999,13 @@ public class BuildCode {
            else
                output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
        }
-       
 
        /* Generate labels first */
        HashSet tovisit=new HashSet();
        HashSet visited=new HashSet();
        int labelindex=0;
        Hashtable nodetolabel=new Hashtable();
-       tovisit.add(fm.methodEntryNode());
+       tovisit.add(fm.getNext(0));
        FlatNode current_node=null;
 
        //Assign labels 1st
@@ -855,10 +1029,14 @@ public class BuildCode {
            }
        }
 
+       if (state.THREAD&&GENERATEPRECISEGC) {
+           output.println("checkcollect(&"+localsprefix+");");
+       }
+       
        //Do the actual code generation
        tovisit=new HashSet();
        visited=new HashSet();
-       tovisit.add(fm.methodEntryNode());
+       tovisit.add(fm.getNext(0));
        while(current_node!=null||!tovisit.isEmpty()) {
            if (current_node==null) {
                current_node=(FlatNode)tovisit.iterator().next();
@@ -868,7 +1046,11 @@ public class BuildCode {
            if (nodetolabel.containsKey(current_node))
                output.println("L"+nodetolabel.get(current_node)+":");
            if (state.INSTRUCTIONFAILURE) {
-               output.println("if ((--instructioncount)==0) injectinstructionfailure();");
+               if (state.THREAD) {
+                   output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
+               }
+               else
+                   output.println("if ((--instructioncount)==0) injectinstructionfailure();");
            }
            if (current_node.numNext()==0) {
                output.print("   ");
@@ -909,6 +1091,7 @@ public class BuildCode {
        MethodDescriptor md=fm.getMethod();
        TaskDescriptor task=fm.getTask();
        TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
+
        if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
            return td.getSafeSymbol();
        }
@@ -925,6 +1108,15 @@ public class BuildCode {
 
     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
        switch(fn.kind()) {
+       case FKind.FlatAtomicEnterNode:
+           generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
+           return;
+       case FKind.FlatAtomicExitNode:
+           generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
+           return;
+       case FKind.FlatTagDeclaration:
+           generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
+           return;
        case FKind.FlatCall:
            generateFlatCall(fm, (FlatCall) fn,output);
            return;
@@ -958,6 +1150,12 @@ public class BuildCode {
        case FKind.FlatNop:
            output.println("/* nop */");
            return;
+       case FKind.FlatBackEdge:
+           if (state.THREAD&&GENERATEPRECISEGC) {
+               output.println("checkcollect(&"+localsprefix+");");
+           } else
+               output.println("/* nop */");
+           return;
        case FKind.FlatCheckNode:
            generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
            return;
@@ -968,17 +1166,20 @@ public class BuildCode {
        throw new Error();
 
     }
+    
+    public void generateFlatAtomicEnterNode(FlatMethod fm,  FlatAtomicEnterNode faen, PrintWriter output) {
+    }
 
-    private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
+    public void generateFlatAtomicExitNode(FlatMethod fm,  FlatAtomicExitNode faen, PrintWriter output) {
+    }
 
+    private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
        if (state.CONSCHECK) {
            String specname=fcn.getSpec();
            String varname="repairstate___";
            output.println("{");
-
            output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
 
-
            TempDescriptor[] temps=fcn.getTemps();
            String[] vars=fcn.getVars();
            for(int i=0;i<temps.length;i++) {
@@ -992,7 +1193,6 @@ public class BuildCode {
            output.println("free"+specname+"_state("+varname+");");
            output.println("abort_task();");
            output.println("}");
-
            output.println("}");
        }
     }
@@ -1005,19 +1205,24 @@ public class BuildCode {
        if (GENERATEPRECISEGC) {
            output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
            
-           output.print(objectparams.getUID());
+           output.print(objectparams.numPointers());
+           //      output.print(objectparams.getUID());
            output.print(", & "+localsprefix);
            if (fc.getThis()!=null) {
                output.print(", ");
-               output.print(generateTemp(fm,fc.getThis()));
+               output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
            }
            for(int i=0;i<fc.numArgs();i++) {
-               VarDescriptor var=md.getParameter(i);
+               Descriptor var=md.getParameter(i);
                TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
                if (objectparams.isParamPtr(paramtemp)) {
                    TempDescriptor targ=fc.getArg(i);
                    output.print(", ");
-                   output.print(generateTemp(fm, targ));
+                   TypeDescriptor td=md.getParamType(i);
+                   if (td.isTag())
+                       output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
+                   else
+                       output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
                }
            }
            output.println("};");
@@ -1076,7 +1281,7 @@ public class BuildCode {
            }
        }
        for(int i=0;i<fc.numArgs();i++) {
-           VarDescriptor var=md.getParameter(i);
+           Descriptor var=md.getParameter(i);
            TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
            if (objectparams.isParamPrim(paramtemp)) {
                TempDescriptor targ=fc.getArg(i);
@@ -1160,9 +1365,27 @@ public class BuildCode {
     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
        if (fn.getType().isArray()) {
            int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
-           output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
-       } else
-           output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
+           if (GENERATEPRECISEGC) {
+               output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
+           } else {
+               output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
+           }
+       } else {
+           if (GENERATEPRECISEGC) {
+               output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+           } else {
+               output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
+           }
+       }
+    }
+
+
+    private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
+       if (GENERATEPRECISEGC) {
+           output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
+       } else {
+           output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
+       }
     }
 
     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
@@ -1184,7 +1407,7 @@ public class BuildCode {
     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
        /* TODO: Do type check here */
        if (fcn.getType().isArray()) {
-           ;
+           throw new Error();
        } else if (fcn.getType().isClass())
            output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
        else
@@ -1194,9 +1417,13 @@ public class BuildCode {
     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
        if (fln.getValue()==null)
            output.println(generateTemp(fm, fln.getDst())+"=0;");
-       else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
-           output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
-       else if (fln.getType().isBoolean()) {
+       else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
+           if (GENERATEPRECISEGC) {
+               output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+           } else {
+               output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+           }
+       } else if (fln.getType().isBoolean()) {
            if (((Boolean)fln.getValue()).booleanValue())
                output.println(generateTemp(fm, fln.getDst())+"=1;");
            else
@@ -1209,7 +1436,6 @@ public class BuildCode {
     }
 
     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
-       
        if (frn.getReturnTemp()!=null)
            output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
        else
@@ -1220,7 +1446,10 @@ public class BuildCode {
        output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
     }
 
-    private void generateHeader(Descriptor des, PrintWriter output) {
+    /** This method generates header information for the method or
+     * task referenced by the Descriptor des. */
+
+    private void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
        /* Print header */
        ParamsObject objectparams=(ParamsObject)paramstable.get(des);
        MethodDescriptor md=null;
@@ -1252,9 +1481,10 @@ public class BuildCode {
            else
                output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
            printcomma=true;
-       } 
+       }
 
        if (md!=null) {
+           /* Method */
            for(int i=0;i<objectparams.numPrimitives();i++) {
                TempDescriptor temp=objectparams.getPrimitive(i);
                if (printcomma)
@@ -1267,61 +1497,470 @@ public class BuildCode {
            }
            output.println(") {");
        } else if (!GENERATEPRECISEGC) {
+           /* Imprecise Task */
            output.println("void * parameterarray[]) {");
+           /* Unpack variables */
            for(int i=0;i<objectparams.numPrimitives();i++) {
                TempDescriptor temp=objectparams.getPrimitive(i);
                output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
            }
-           if (objectparams.numPrimitives()>maxtaskparams)
-               maxtaskparams=objectparams.numPrimitives();
-       } else output.println(" {");
-    }
+           for(int i=0;i<fm.numTags();i++) {
+               TempDescriptor temp=fm.getTag(i);
+               int offset=i+objectparams.numPrimitives();
+               output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
+           }
 
+           if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
+               maxtaskparams=objectparams.numPrimitives()+fm.numTags();
+       } else output.println(") {");
+    }
+    
     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
        output.println("/* FlatFlagActionNode */");
+
+
+       /* Process tag changes */
+       Relation tagsettable=new Relation();
+       Relation tagcleartable=new Relation();
+
+       Iterator tagsit=ffan.getTempTagPairs(); 
+       while (tagsit.hasNext()) {
+           TempTagPair ttp=(TempTagPair) tagsit.next();
+           TempDescriptor objtmp=ttp.getTemp();
+           TagDescriptor tag=ttp.getTag();
+           TempDescriptor tagtmp=ttp.getTagTemp();
+           boolean tagstatus=ffan.getTagChange(ttp);
+           if (tagstatus) {
+               tagsettable.put(objtmp, tagtmp);
+           } else {
+               tagcleartable.put(objtmp, tagtmp);
+           }
+       }
+
+
        Hashtable flagandtable=new Hashtable();
        Hashtable flagortable=new Hashtable();
 
-
+       /* Process flag changes */
        Iterator flagsit=ffan.getTempFlagPairs();
        while(flagsit.hasNext()) {
            TempFlagPair tfp=(TempFlagPair)flagsit.next();
            TempDescriptor temp=tfp.getTemp();
            Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
            FlagDescriptor flag=tfp.getFlag();
-           int flagid=1<<((Integer)flagtable.get(flag)).intValue();
-           boolean flagstatus=ffan.getFlagChange(tfp);
-           if (flagstatus) {
-               int mask=0;
+           if (flag==null) {
+               //Newly allocate objects that don't set any flags case
                if (flagortable.containsKey(temp)) {
-                   mask=((Integer)flagortable.get(temp)).intValue();
+                   throw new Error();
                }
-               mask|=flagid;
+               int mask=0;
                flagortable.put(temp,new Integer(mask));
            } else {
-               int mask=0xFFFFFFFF;
-               if (flagandtable.containsKey(temp)) {
-                   mask=((Integer)flagandtable.get(temp)).intValue();
+               int flagid=1<<((Integer)flagtable.get(flag)).intValue();
+               boolean flagstatus=ffan.getFlagChange(tfp);
+               if (flagstatus) {
+                   int mask=0;
+                   if (flagortable.containsKey(temp)) {
+                       mask=((Integer)flagortable.get(temp)).intValue();
+                   }
+                   mask|=flagid;
+                   flagortable.put(temp,new Integer(mask));
+               } else {
+                   int mask=0xFFFFFFFF;
+                   if (flagandtable.containsKey(temp)) {
+                       mask=((Integer)flagandtable.get(temp)).intValue();
+                   }
+                   mask&=(0xFFFFFFFF^flagid);
+                   flagandtable.put(temp,new Integer(mask));
                }
-               mask&=(0xFFFFFFFF^flagid);
-               flagandtable.put(temp,new Integer(mask));
            }
        }
-       Iterator orit=flagortable.keySet().iterator();
-       while(orit.hasNext()) {
-           TempDescriptor temp=(TempDescriptor)orit.next();
-           int ormask=((Integer)flagortable.get(temp)).intValue();
+
+
+       HashSet flagtagset=new HashSet();
+       flagtagset.addAll(flagortable.keySet());
+       flagtagset.addAll(flagandtable.keySet());
+       flagtagset.addAll(tagsettable.keySet());
+       flagtagset.addAll(tagcleartable.keySet());
+
+       Iterator ftit=flagtagset.iterator();
+       while(ftit.hasNext()) {
+           TempDescriptor temp=(TempDescriptor)ftit.next();
+           
+           
+           Set tagtmps=tagcleartable.get(temp);
+           if (tagtmps!=null) {
+               Iterator tagit=tagtmps.iterator();
+               while(tagit.hasNext()) {
+                   TempDescriptor tagtmp=(TempDescriptor)tagit.next();
+                   if (GENERATEPRECISEGC) 
+                       output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                   else
+                       output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+               }
+           }
+
+           tagtmps=tagsettable.get(temp);
+           if (tagtmps!=null) {
+               Iterator tagit=tagtmps.iterator();
+               while(tagit.hasNext()) {
+                   TempDescriptor tagtmp=(TempDescriptor)tagit.next();
+                   if (GENERATEPRECISEGC)
+                       output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                   else
+                       output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+               }
+           }
+
+           int ormask=0;
            int andmask=0xFFFFFFF;
+           
+           if (flagortable.containsKey(temp))
+               ormask=((Integer)flagortable.get(temp)).intValue();
            if (flagandtable.containsKey(temp))
                andmask=((Integer)flagandtable.get(temp)).intValue();
-           output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
-       }
-       Iterator andit=flagandtable.keySet().iterator();
-       while(andit.hasNext()) {
-           TempDescriptor temp=(TempDescriptor)andit.next();
-           int andmask=((Integer)flagandtable.get(temp)).intValue();
-           if (!flagortable.containsKey(temp))
-               output.println("flagorand("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");");
+           if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
+               output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
+           } else {
+               output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
+           }
        }
     }
+
+     void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
+        
+        //GENERATE HEADERS
+        headers.println("#include \"task.h\"\n\n");
+        
+
+        
+        //STRUCT PREDICATEMEMBER
+        headers.println("struct predicatemember{");
+        headers.println("int type;");
+        headers.println("int numdnfterms;");
+        headers.println("int * flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;\n};\n\n");
+
+        //STRUCT EXITFLAGSTATE
+        headers.println("struct exitflagstate{");
+        headers.println("int numflags;");
+        headers.println("int * flags;");
+        /*
+          headers.println("int numtags;");
+          headers.println("int * tags;");
+        */
+        headers.println("\n};\n\n");
+        
+        //STRUCT EXITSTATES
+        headers.println("struct exitstates{");
+        headers.println("int numexitflagstates;");
+        headers.println("struct exitflagstate * exitflagstatearray;\n};\n\n");
+
+        //STRUCT OPTIONALTASKDESCRIPTOR
+        headers.println("struct optionaltaskdescriptor{");
+        headers.println("struct taskdescriptor * task;");
+        headers.println("int numpredicatemembers;");
+        headers.println("struct predicatemember * predicatememberarray;");
+        headers.println("int numexitstates;");
+        headers.println("struct existates * exitstatesarray;\n};\n\n");
+                
+        //STRUCT FSANALYSISWRAPPER
+        headers.println("struct fsanalysiswrapper{");
+        headers.println("int numflags;");
+        headers.println("int * flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;");
+        headers.println("int numoptionaltaskdescriptors;");
+        headers.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray;\n};\n\n");
+
+        //STRUCT CLASSANALYSISWRAPPER
+        headers.println("struct classanalyiswrapper{");
+        headers.println("int type;");
+        headers.println("int numfsanalysiswrappers;");
+        headers.println("struct fsanalysiswrapper * fsanalysiswrapperarray;\n};\n\n");
+
+        Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+        while(taskit.hasNext()) {
+            TaskDescriptor td=(TaskDescriptor)taskit.next();
+            headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
+        }
+        
+                                                  
+        
+        //GENERATE STRUCTS
+        output.println("#include \"optionalstruct.h\"\n\n");    
+        HashSet processedcd = new HashSet();
+       
+
+        Enumeration e = safeexecution.keys();
+        while (e.hasMoreElements()) {
+            
+            //get the class
+            ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
+            Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
+            
+            //Generate the struct of optionals
+            if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
+            Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
+            if( !c_otd.isEmpty() ){
+                for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
+                    OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
+                    
+                    //generate the int arrays for the predicate
+                    Predicate predicate = otd.predicate;
+                    int predicateindex = 0;
+                    //iterate through the classes concerned by the predicate
+                    Collection c_vard = predicate.vardescriptors.values();
+                    for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
+                        VarDescriptor vard = (VarDescriptor)vard_it.next();
+                        TypeDescriptor typed = vard.getType();
+                        
+                        //generate for flags
+                        HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
+                        output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                        int numberterms=0;
+                        if (fen_hashset!=null){
+                            for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
+                                FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
+                                if (fen==null) {
+                                    //output.println("0x0, 0x0 };");
+                                    //numberterms+=1;
+                                }
+                                else {
+                                    
+                                    DNFFlag dflag=fen.getDNF();
+                                    numberterms+=dflag.size();
+                                    
+                                    Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
+                                    
+                                    for(int j=0;j<dflag.size();j++) {
+                                        if (j!=0)
+                                            output.println(",");
+                                        Vector term=dflag.get(j);
+                                        int andmask=0;
+                                        int checkmask=0;
+                                        for(int k=0;k<term.size();k++) {
+                                            DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
+                                            FlagDescriptor fd=dfa.getFlag();
+                                            boolean negated=dfa.getNegated();
+                                            int flagid=1<<((Integer)flags.get(fd)).intValue();
+                                            andmask|=flagid;
+                                            if (!negated)
+                                                checkmask|=flagid;
+                                        }
+                                        output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
+                                    }
+                                }
+                            }
+                        }
+                        output.println("};\n");
+                        
+                        //generate for tags
+                        TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
+                        output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                        //BUG...added next line to fix, test with any task program
+                        int numtags = 0;
+                        if (tagel!=null){
+                            for(int j=0;j<tagel.numTags();j++) {
+                                if (j!=0)
+                                    output.println(",");
+                                /* for each tag we need */
+                                /* which slot it is */
+                                /* what type it is */
+                                //TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(tagel.getName(j));
+                                TempDescriptor tmp=tagel.getTemp(j);
+                                //got rid of slot
+                                output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
+                            }
+                            numtags = tagel.numTags();
+                        }
+                        output.println("};");
+                        
+                        //store the result into a predicatemember struct
+                        output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                        output.println("/*type*/"+typed.getClassDesc().getId()+",");
+                        output.println("/* number of dnf terms */"+numberterms+",");
+                        output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        output.println("/* number of tag */"+numtags+",");
+                        output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        output.println("};\n");
+                        predicateindex++;
+                    }
+                    
+
+                    //generate an array that stores the entire predicate
+                    output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                    for( int j = 0; j<predicateindex; j++){
+                        if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    }
+
+                    //generate the struct for possible exitfses
+                    HashSet<HashSet> exitfses = otd.exitfses;
+                    int exitindex = 0;
+                    int nbexit = exitfses.size();
+                    int fsnumber;
+                    
+                    //iterate through possible exits
+                    for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
+                        HashSet temp_hashset = (HashSet)exitfseshash.next();
+                        fsnumber = 0 ;
+                        
+                        //iterate through possible FSes corresponding to the exit
+                        for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
+                           FlagState fs = (FlagState)exfses.next();
+                           fsnumber++;
+                           output.println("int flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                           int counterflag = 0;
+                           for(Iterator flags = fs.getFlags(); flags.hasNext();){
+                               FlagDescriptor flagd = (FlagDescriptor)flags.next();
+                               int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
+                               if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
+                               else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
+                               counterflag++;
+                           } 
+                           output.println("};\n");
+                           //do the same for tags;
+                           //maybe not needed because no tag changes tolerated.
+
+                           //store the information into a struct
+                           output.println("struct exitflagstate exitflagstate"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                           output.println("/*number of flags*/"+counterflag+",");
+                           output.println("flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                           output.println("};\n");
+                        }
+                        
+                        //store fses corresponding to this exit into an array
+                        output.println("struct exitflagstate * exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+" [] = {");
+                        for( int j = 0; j<fsnumber; j++){
+                            if( j != fsnumber-1)output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"'");
+                            else output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                        }
+                        
+                        //store that information in a struct
+                        output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                        output.println("/*number of exitflagstate*/"+fsnumber+",");
+                        output.println("exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                        output.println("};\n");
+
+                        exitindex++;
+                    }
+                    
+                    //store the information concerning all exits into an array
+                    output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                    for( int j = 0; j<nbexit; j++){
+                        if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    }
+                                    
+                                    
+                    //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
+                    output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                    output.println("task_"+otd.td.getSafeSymbol()+",");
+                    output.println("/*number of members */"+predicateindex+",");
+                    output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                    output.println("/*number of exit fses */"+nbexit+",");
+                    output.println("exitstatearray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                    output.println("};\n");
+                }      
+            }
+            else continue; // if there is no optionals, there is no need to build the rest of the struct 
+            
+            //get all the possible falgstates reachable by an object
+            Hashtable hashtbtemp = safeexecution.get(cdtemp);
+            Enumeration fses = hashtbtemp.keys();
+            int fscounter = 0;
+            while(fses.hasMoreElements()){
+                FlagState fs = (FlagState)fses.nextElement();
+                fscounter++;
+                
+                //get the set of OptionalTaskDescriptors corresponding
+                HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
+                //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
+                
+                output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
+                for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
+                    OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
+                    if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    
+                    else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                }
+
+                //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
+                
+                output.println("int flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
+                for(Iterator flags = fs.getFlags(); flags.hasNext();){
+                    FlagDescriptor flagd = (FlagDescriptor)flags.next();
+                    int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
+                    if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
+                    else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
+                    
+                }
+                //process tag information
+                
+                int tagcounter = 0;
+                //TagExpressionList tagel = fs.getTags(); 
+                //output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                //BUG...added next line to fix, test with any task program
+                
+                //if (tagel!=null){
+                //    for(int j=0;j<tagel.numTags();j++) {
+                //      if (j!=0)
+                //          output.println(",");
+                //      TempDescriptor tmp=tagel.getTemp(j);
+                //      output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
+                //   }
+                //  numtags = tagel.numTags();
+                //}
+                //output.println("};");
+                
+                
+                //Store the result in fsanalysiswrapper
+                output.println("};\n");
+                output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
+                output.println("/* number of flags*/"+fs.numFlags()+",");
+                output.println("flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                output.println("/* number of tags*/"+tagcounter+",");
+                output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
+                output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
+                output.println("};\n");
+                
+            }
+
+            //Build the array of fsanalysiswrappers
+            output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
+            for(int i = 0; i<fscounter; i++){
+                if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
+                        
+                    else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
+            }
+
+            //Build the classanalysiswrapper referring to the previous array
+            output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
+            output.println("/*type*/"+cdtemp.getId()+",");
+            output.println("/* number of fsanalysiswrappers */"+fscounter+",");
+            output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
+            fscounter = 0;
+            processedcd.add(cdtemp);
+        }
+
+        //build an array containing every classes for which code has been build
+        output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
+        for(Iterator classit = processedcd.iterator(); classit.hasNext();){
+            ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
+            if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
+            else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
+        }
+        output.println("int numclasses = "+processedcd.size()+";");
+        
+     }
+    
 }
+        
+
+
+
+
+