more organizing code
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.FlagExpressionNode;
3 import IR.Tree.DNFFlag;
4 import IR.Tree.DNFFlagAtom;
5 import IR.Tree.TagExpressionList;
6 import IR.*;
7 import java.util.*;
8 import java.io.*;
9 import Util.Relation;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
12 import Analysis.TaskStateAnalysis.Predicate;
13
14 public class BuildCode {
15     State state;
16     Hashtable temptovar;
17     Hashtable paramstable;
18     Hashtable tempstable;
19     Hashtable fieldorder;
20     Hashtable flagorder;
21     int tag=0;
22     String localsprefix="___locals___";
23     String paramsprefix="___params___";
24     public static boolean GENERATEPRECISEGC=false;
25     public static String PREFIX="";
26     public static String arraytype="ArrayObject";
27     Virtual virtualcalls;
28     TypeUtil typeutil;
29     private int maxtaskparams=0;
30     private int maxcount=0;
31     ClassDescriptor[] cdarray;
32     TypeDescriptor[] arraytable;
33    
34     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
35         state=st;
36         this.temptovar=temptovar;
37         paramstable=new Hashtable();    
38         tempstable=new Hashtable();
39         fieldorder=new Hashtable();
40         flagorder=new Hashtable();
41         this.typeutil=typeutil;
42         virtualcalls=new Virtual(state);
43     }
44
45     /** The buildCode method outputs C code for all the methods.  The Flat
46      * versions of the methods must already be generated and stored in
47      * the State object. */
48
49     public void buildCode() {
50         /* Create output streams to write to */
51         PrintWriter outclassdefs=null;
52         PrintWriter outstructs=null;
53         PrintWriter outrepairstructs=null;
54         PrintWriter outmethodheader=null;
55         PrintWriter outmethod=null;
56         PrintWriter outvirtual=null;
57         PrintWriter outtask=null;
58         PrintWriter outtaskdefs=null;
59         PrintWriter outoptionalarrays=null;
60         PrintWriter optionalheaders=null;
61
62         try {
63             outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
64             outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
65             outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
66             outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
67             outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
68             if (state.TASK) {
69                 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
70                 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
71                 if (state.OPTIONAL){
72                     outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
73                     optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
74                 } 
75             }
76             if (state.structfile!=null) {
77                 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
78             }
79         } catch (Exception e) {
80             e.printStackTrace();
81             System.exit(-1);
82         }
83
84         /* Build the virtual dispatch tables */
85         buildVirtualTables(outvirtual);
86
87         /* Output includes */
88         outmethodheader.println("#ifndef METHODHEADERS_H");
89         outmethodheader.println("#define METHODHEADERS_H");
90         outmethodheader.println("#include \"structdefs.h\"");
91
92         /* Output Structures */
93         outputStructs(outstructs);
94
95         // Output the C class declarations
96         // These could mutually reference each other
97         outputClassDeclarations(outclassdefs);
98
99         // Output function prototypes and structures for parameters
100         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
101         while(it.hasNext()) {
102             ClassDescriptor cn=(ClassDescriptor)it.next();
103             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
104         }
105         outclassdefs.close();
106
107         if (state.TASK) {
108             /* Map flags to integers */
109             /* The runtime keeps track of flags using these integers */
110             it=state.getClassSymbolTable().getDescriptorsIterator();
111             while(it.hasNext()) {
112                 ClassDescriptor cn=(ClassDescriptor)it.next();
113                 mapFlags(cn);
114             }
115             /* Generate Tasks */
116             generateTaskStructs(outstructs, outmethodheader);
117
118             /* Outputs generic task structures if this is a task
119                program */
120             outputTaskTypes(outtask);
121         }
122
123         /* Build the actual methods */
124         outputMethods(outmethod);
125
126         if (state.TASK) {
127             /* Output code for tasks */
128             outputTaskCode(outtaskdefs, outmethod);
129             outtaskdefs.close();
130             /* Record maximum number of task parameters */
131             outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
132         } else if (state.main!=null) {
133             /* Generate main method */
134             outputMainMethod(outmethod);
135         }
136         
137         /* Generate information for task with optional parameters */
138         if (state.TASK&&state.OPTIONAL){
139             generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
140             outoptionalarrays.close();
141         } 
142
143         /* Output structure definitions for repair tool */
144         if (state.structfile!=null) {
145             buildRepairStructs(outrepairstructs);
146             outrepairstructs.close();
147         }
148
149         /* Close files */
150         outmethodheader.println("#endif");
151         outmethodheader.close();
152         outmethod.close();
153         outstructs.println("#endif");
154         outstructs.close();
155     }
156
157     /* This code just generates the main C method for java programs.
158      * The main C method packs up the arguments into a string array
159      * and passes it to the java main method. */
160
161     private void outputMainMethod(PrintWriter outmethod) {
162         outmethod.println("int main(int argc, const char *argv[]) {");
163         outmethod.println("  int i;");
164         if (GENERATEPRECISEGC) {
165             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
166         } else {
167             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
168         }
169         if (state.THREAD) {
170             outmethod.println("initializethreads();");
171         }
172         outmethod.println("  for(i=1;i<argc;i++) {");
173         outmethod.println("    int length=strlen(argv[i]);");
174         if (GENERATEPRECISEGC) {
175             outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
176         } else {
177             outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
178         }
179         outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
180         outmethod.println("  }");
181         
182         
183         MethodDescriptor md=typeutil.getMain();
184         ClassDescriptor cd=typeutil.getMainClass();
185         
186         outmethod.println("   {");
187         if (GENERATEPRECISEGC) {
188             outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
189             outmethod.println("1, NULL,"+"stringarray};");
190             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
191         } else
192             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
193         outmethod.println("   }");
194         
195         if (state.THREAD) {
196             outmethod.println("pthread_mutex_lock(&gclistlock);");
197             outmethod.println("threadcount--;");
198             outmethod.println("pthread_cond_signal(&gccond);");
199             outmethod.println("pthread_mutex_unlock(&gclistlock);");
200             outmethod.println("pthread_exit(NULL);");
201         }
202         outmethod.println("}");
203     }
204
205     /* This method outputs code for each task. */
206
207     private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
208         /* Compile task based program */
209         outtaskdefs.println("#include \"task.h\"");
210         outtaskdefs.println("#include \"methodheaders.h\"");
211         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
212         while(taskit.hasNext()) {
213             TaskDescriptor td=(TaskDescriptor)taskit.next();
214             FlatMethod fm=state.getMethodFlat(td);
215             generateFlatMethod(fm, outmethod);
216             generateTaskDescriptor(outtaskdefs, fm, td);
217         }
218         
219         //Output task descriptors
220         taskit=state.getTaskSymbolTable().getDescriptorsIterator();
221         outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
222         boolean first=true;
223         while(taskit.hasNext()) {
224             TaskDescriptor td=(TaskDescriptor)taskit.next();
225             if (first)
226                 first=false;
227             else
228                 outtaskdefs.println(",");
229             outtaskdefs.print("&task_"+td.getSafeSymbol());
230         }
231         outtaskdefs.println("};");
232
233         outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
234     }
235
236     /* This method outputs most of the methods.c file.  This includes
237      * some standard includes and then an array with the sizes of
238      * objets and array that stores supertype and then the code for
239      * the Java methods.. */
240
241     private void outputMethods(PrintWriter outmethod) {
242         outmethod.println("#include \"methodheaders.h\"");
243         outmethod.println("#include \"virtualtable.h\"");
244         outmethod.println("#include <runtime.h>");
245         if (state.THREAD)
246             outmethod.println("#include <thread.h>");
247         if (state.main!=null) {
248             outmethod.println("#include <string.h>");       
249         }
250         if (state.CONSCHECK) {
251             outmethod.println("#include \"checkers.h\"");
252         }
253         //Store the sizes of classes & array elements
254         generateSizeArray(outmethod);
255         
256         //Store table of supertypes
257         generateSuperTypeTable(outmethod);
258
259         //Store the layout of classes
260         generateLayoutStructs(outmethod);
261
262         /* Generate code for methods */
263         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
264         while(classit.hasNext()) {
265             ClassDescriptor cn=(ClassDescriptor)classit.next();
266             Iterator methodit=cn.getMethods();
267             while(methodit.hasNext()) {
268                 /* Classify parameters */
269                 MethodDescriptor md=(MethodDescriptor)methodit.next();
270                 FlatMethod fm=state.getMethodFlat(md);
271                 if (!md.getModifiers().isNative())
272                     generateFlatMethod(fm,outmethod);
273             }
274         }
275     }
276
277     private void outputStructs(PrintWriter outstructs) {
278         outstructs.println("#ifndef STRUCTDEFS_H");
279         outstructs.println("#define STRUCTDEFS_H");
280         outstructs.println("#include \"classdefs.h\"");
281
282         /* Output #defines that the runtime uses to determine type
283          * numbers for various objects it needs */
284
285         outstructs.println("#define STRINGARRAYTYPE "+
286                            (state.getArrayNumber(
287                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
288
289         outstructs.println("#define OBJECTARRAYTYPE "+
290                            (state.getArrayNumber(
291                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
292
293
294         outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
295         outstructs.println("#define CHARARRAYTYPE "+
296                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
297
298         outstructs.println("#define BYTEARRAYTYPE "+
299                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
300
301         outstructs.println("#define BYTEARRAYARRAYTYPE "+
302                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
303         
304         outstructs.println("#define NUMCLASSES "+state.numClasses());
305         if (state.TASK) {
306             outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
307             outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
308             outstructs.println("#define TAGARRAYTYPE "+
309                                (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
310         }
311     }
312
313     private void outputClassDeclarations(PrintWriter outclassdefs) {
314         if (state.THREAD)
315             outclassdefs.println("#include <pthread.h>");
316         outclassdefs.println("struct "+arraytype+";");
317         /* Start by declaring all structs */
318         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
319         while(it.hasNext()) {
320             ClassDescriptor cn=(ClassDescriptor)it.next();
321             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
322         }
323         outclassdefs.println("");
324         //Print out definition for array type
325         outclassdefs.println("struct "+arraytype+" {");
326         outclassdefs.println("  int type;");
327         if (state.THREAD) {
328             outclassdefs.println("  pthread_t tid;");
329             outclassdefs.println("  void * lockentry;");
330             outclassdefs.println("  int lockcount;");
331         }
332         if (state.TASK) {
333             outclassdefs.println("  int flag;");
334             outclassdefs.println("  void * flagptr;");
335             if(state.OPTIONAL) outclassdefs.println("  int failedstatus;");
336         }
337         printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
338         
339         outclassdefs.println("  int ___length___;");
340         outclassdefs.println("};\n");
341         outclassdefs.println("extern int classsize[];");
342         outclassdefs.println("extern int hasflags[];");
343         outclassdefs.println("extern int * pointerarray[];");
344         outclassdefs.println("extern int supertypes[];");
345     }
346
347     /** Prints out definitions for generic task structures */
348
349     private void outputTaskTypes(PrintWriter outtask) {
350         outtask.println("#ifndef _TASK_H");
351         outtask.println("#define _TASK_H");
352         outtask.println("struct parameterdescriptor {");
353         outtask.println("int type;");
354         outtask.println("int numberterms;");
355         outtask.println("int *intarray;");
356         outtask.println("void * queue;");
357         outtask.println("int numbertags;");
358         outtask.println("int *tagarray;");
359         outtask.println("};");
360         
361         outtask.println("struct taskdescriptor {");
362         outtask.println("void * taskptr;");
363         outtask.println("int numParameters;");
364         outtask.println("int numTotal;");
365         outtask.println("struct parameterdescriptor **descriptorarray;");
366         outtask.println("char * name;");
367         outtask.println("};");
368         outtask.println("extern struct taskdescriptor * taskarray[];");
369         outtask.println("extern numtasks;");
370         outtask.println("#endif");
371     }
372
373
374     private void buildRepairStructs(PrintWriter outrepairstructs) {
375         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
376         while(classit.hasNext()) {
377             ClassDescriptor cn=(ClassDescriptor)classit.next();
378             outrepairstructs.println("structure "+cn.getSymbol()+" {");
379             outrepairstructs.println("  int __type__;");
380             if (state.TASK) {
381                 outrepairstructs.println("  int __flag__;");
382                 outrepairstructs.println("  int __flagptr__;");
383             }
384             printRepairStruct(cn, outrepairstructs);
385             outrepairstructs.println("}\n");
386         }
387         
388         for(int i=0;i<state.numArrays();i++) {
389             TypeDescriptor tdarray=arraytable[i];
390             TypeDescriptor tdelement=tdarray.dereference();
391             outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
392             outrepairstructs.println("  int __type__;");
393             printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
394             outrepairstructs.println("  int length;");
395             /*
396               // Need to add support to repair tool for this
397               if (tdelement.isClass()||tdelement.isArray())
398                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
399             else
400                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
401             */
402             outrepairstructs.println("}\n");
403         }
404     }
405
406     private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
407         ClassDescriptor sp=cn.getSuperDesc();
408         if (sp!=null)
409             printRepairStruct(sp, output);
410         
411         Vector fields=(Vector)fieldorder.get(cn);
412
413         for(int i=0;i<fields.size();i++) {
414             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
415             if (fd.getType().isArray()) {
416                 output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
417             } else if (fd.getType().isClass())
418                 output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
419             else if (fd.getType().isFloat())
420                 output.println("  int "+fd.getSymbol()+"; /* really float */");
421             else 
422                 output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
423         }
424     }
425
426     /** This method outputs TaskDescriptor information */
427     void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
428         for (int i=0;i<task.numParameters();i++) {
429             VarDescriptor param_var=task.getParameter(i);
430             TypeDescriptor param_type=task.getParamType(i);
431             FlagExpressionNode param_flag=task.getFlag(param_var);
432             TagExpressionList param_tag=task.getTag(param_var);
433
434             int dnfterms;
435             if (param_flag==null) {
436                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
437                 output.println("0x0, 0x0 };");
438                 dnfterms=1;
439             } else {
440                 DNFFlag dflag=param_flag.getDNF();
441                 dnfterms=dflag.size();
442                 
443                 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
444                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
445                 for(int j=0;j<dflag.size();j++) {
446                     if (j!=0)
447                         output.println(",");
448                     Vector term=dflag.get(j);
449                     int andmask=0;
450                     int checkmask=0;
451                     for(int k=0;k<term.size();k++) {
452                         DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
453                         FlagDescriptor fd=dfa.getFlag();
454                         boolean negated=dfa.getNegated();
455                         int flagid=1<<((Integer)flags.get(fd)).intValue();
456                         andmask|=flagid;
457                         if (!negated)
458                             checkmask|=flagid;
459                     }
460                     output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
461                 }
462                 output.println("};");
463             }
464
465             output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
466             //BUG...added next line to fix, test with any task program
467             if (param_tag!=null)
468                 for(int j=0;j<param_tag.numTags();j++) {
469                     if (j!=0)
470                         output.println(",");
471                     /* for each tag we need */
472                     /* which slot it is */
473                     /* what type it is */
474                     TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
475                     TempDescriptor tmp=param_tag.getTemp(j);
476                     int slot=fm.getTagInt(tmp);
477                     output.println(slot+", "+state.getTagId(tvd.getTag()));
478                 }
479             output.println("};");
480
481             output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
482             output.println("/* type */"+param_type.getClassDesc().getId()+",");
483             output.println("/* number of DNF terms */"+dnfterms+",");
484             output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
485             output.println("0,");
486             //BUG, added next line to fix and else statement...test
487             //with any task program
488             if (param_tag!=null)
489                 output.println("/* number of tags */"+param_tag.numTags()+",");
490             else
491                 output.println("/* number of tags */ 0,");
492             output.println("parametertag_"+i+"_"+task.getSafeSymbol());
493             output.println("};");
494         }
495
496
497         output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
498         for (int i=0;i<task.numParameters();i++) {
499             if (i!=0)
500                 output.println(",");
501             output.print("&parameter_"+i+"_"+task.getSafeSymbol());
502         }
503         output.println("};");
504
505         output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
506         output.println("&"+task.getSafeSymbol()+",");
507         output.println("/* number of parameters */" +task.numParameters() + ",");
508         int numtotal=task.numParameters()+fm.numTags();
509         output.println("/* number total parameters */" +numtotal + ",");
510         output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
511         output.println("\""+task.getSymbol()+"\"");
512         output.println("};");
513     }
514
515
516     /** The buildVirtualTables method outputs the virtual dispatch
517      * tables for methods. */
518
519     private void buildVirtualTables(PrintWriter outvirtual) {
520         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
521         while(classit.hasNext()) {
522             ClassDescriptor cd=(ClassDescriptor)classit.next();
523             if (virtualcalls.getMethodCount(cd)>maxcount)
524                 maxcount=virtualcalls.getMethodCount(cd);
525         }
526         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
527
528         /* Fill in virtual table */
529         classit=state.getClassSymbolTable().getDescriptorsIterator();
530         while(classit.hasNext()) {
531             ClassDescriptor cd=(ClassDescriptor)classit.next();
532             fillinRow(cd, virtualtable, cd.getId());
533         }
534
535         ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
536         Iterator arrayit=state.getArrayIterator();
537         while(arrayit.hasNext()) {
538             TypeDescriptor td=(TypeDescriptor)arrayit.next();
539             int id=state.getArrayNumber(td);
540             fillinRow(objectcd, virtualtable, id+state.numClasses());
541         }
542         
543         outvirtual.print("void * virtualtable[]={");
544         boolean needcomma=false;
545         for(int i=0;i<state.numClasses()+state.numArrays();i++) {
546             for(int j=0;j<maxcount;j++) {
547                 if (needcomma)
548                     outvirtual.print(", ");
549                 if (virtualtable[i][j]!=null) {
550                     MethodDescriptor md=virtualtable[i][j];
551                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
552                 } else {
553                     outvirtual.print("0");
554                 }
555                 needcomma=true;
556             }
557             outvirtual.println("");
558         }
559         outvirtual.println("};");
560         outvirtual.close();
561     }
562
563     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
564         /* Get inherited methods */
565         if (cd.getSuperDesc()!=null)
566             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
567         /* Override them with our methods */
568         for(Iterator it=cd.getMethods();it.hasNext();) {
569             MethodDescriptor md=(MethodDescriptor)it.next();
570             if (md.isStatic()||md.getReturnType()==null)
571                 continue;
572             int methodnum=virtualcalls.getMethodNumber(md);
573             virtualtable[rownum][methodnum]=md;
574         }
575     }
576
577     /** Generate array that contains the sizes of class objects.  The
578      * object allocation functions in the runtime use this
579      * information. */
580
581     private void generateSizeArray(PrintWriter outclassdefs) {
582         outclassdefs.print("int classsize[]={");
583         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
584         cdarray=new ClassDescriptor[state.numClasses()];
585         while(it.hasNext()) {
586             ClassDescriptor cd=(ClassDescriptor)it.next();
587             cdarray[cd.getId()]=cd;
588         }
589         boolean needcomma=false;
590         for(int i=0;i<state.numClasses();i++) {
591             if (needcomma)
592                 outclassdefs.print(", ");
593             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
594             needcomma=true;
595         }
596
597         arraytable=new TypeDescriptor[state.numArrays()];
598
599         Iterator arrayit=state.getArrayIterator();
600         while(arrayit.hasNext()) {
601             TypeDescriptor td=(TypeDescriptor)arrayit.next();
602             int id=state.getArrayNumber(td);
603             arraytable[id]=td;
604         }
605         
606         for(int i=0;i<state.numArrays();i++) {
607             if (needcomma)
608                 outclassdefs.print(", ");
609             TypeDescriptor tdelement=arraytable[i].dereference();
610             if (tdelement.isArray()||tdelement.isClass())
611                 outclassdefs.print("sizeof(void *)");
612             else
613                 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
614             needcomma=true;
615         }
616
617         outclassdefs.println("};");
618     }
619
620     /** Constructs params and temp objects for each method or task.
621      * These objects tell the compiler which temps need to be
622      * allocated.  */
623
624     private void generateTempStructs(FlatMethod fm) {
625         MethodDescriptor md=fm.getMethod();
626         TaskDescriptor task=fm.getTask();
627
628         ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
629         if (md!=null)
630             paramstable.put(md, objectparams);
631         else
632             paramstable.put(task, objectparams);
633
634         for(int i=0;i<fm.numParameters();i++) {
635             TempDescriptor temp=fm.getParameter(i);
636             TypeDescriptor type=temp.getType();
637             if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
638                 objectparams.addPtr(temp);
639             else
640                 objectparams.addPrim(temp);
641         }
642
643         for(int i=0;i<fm.numTags();i++) {
644             TempDescriptor temp=fm.getTag(i);
645             if (GENERATEPRECISEGC)
646                 objectparams.addPtr(temp);
647             else
648                 objectparams.addPrim(temp);
649         }
650
651         TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
652         if (md!=null)
653             tempstable.put(md, objecttemps);
654         else
655             tempstable.put(task, objecttemps);
656
657         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
658             FlatNode fn=(FlatNode)nodeit.next();
659             TempDescriptor[] writes=fn.writesTemps();
660             for(int i=0;i<writes.length;i++) {
661                 TempDescriptor temp=writes[i];
662                 TypeDescriptor type=temp.getType();
663                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
664                     objecttemps.addPtr(temp);
665                 else
666                     objecttemps.addPrim(temp);
667             }
668         }
669     }
670
671     /** This method outputs the following information about classes
672      * and arrays:
673      * (1) For classes, what are the locations of pointers.
674      * (2) For arrays, does the array contain pointers or primitives.
675      * (3) For classes, does the class contain flags.
676      */
677
678     private void generateLayoutStructs(PrintWriter output) {
679         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
680         while(it.hasNext()) {
681             ClassDescriptor cn=(ClassDescriptor)it.next();
682             output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
683             Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
684             int count=0;
685             while(allit.hasNext()) {
686                 FieldDescriptor fd=(FieldDescriptor)allit.next();
687                 TypeDescriptor type=fd.getType();
688                 if (type.isPtr()||type.isArray())
689                     count++;
690             }
691             output.print(count);
692             allit=cn.getFieldTable().getAllDescriptorsIterator();
693             while(allit.hasNext()) {
694                 FieldDescriptor fd=(FieldDescriptor)allit.next();
695                 TypeDescriptor type=fd.getType();
696                 if (type.isPtr()||type.isArray()) {
697                     output.println(",");
698                     output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
699                 }
700             }
701             output.println("};");
702         }
703         output.println("int * pointerarray[]={");
704         boolean needcomma=false;
705         for(int i=0;i<state.numClasses();i++) {
706             ClassDescriptor cn=cdarray[i];
707             if (needcomma)
708                 output.println(",");
709             needcomma=true;
710             output.print(cn.getSafeSymbol()+"_pointers");
711         }
712
713         for(int i=0;i<state.numArrays();i++) {
714             if (needcomma)
715                 output.println(", ");
716             TypeDescriptor tdelement=arraytable[i].dereference();
717             if (tdelement.isArray()||tdelement.isClass())
718                 output.print("((int *)1)");
719             else
720                 output.print("0");
721             needcomma=true;
722         }
723         
724         output.println("};");
725         needcomma=false;
726         output.println("int hasflags[]={");
727         for(int i=0;i<state.numClasses();i++) {
728             ClassDescriptor cn=cdarray[i];
729             if (needcomma)
730                 output.println(", ");
731             needcomma=true;
732             if (cn.hasFlags())
733                 output.print("1");
734             else
735                 output.print("0");
736         }
737         output.println("};");
738     }
739
740     /** Print out table to give us supertypes */
741     private void generateSuperTypeTable(PrintWriter output) {
742         output.println("int supertypes[]={");
743         boolean needcomma=false;
744         for(int i=0;i<state.numClasses();i++) {
745             ClassDescriptor cn=cdarray[i];
746             if (needcomma)
747                 output.println(",");
748             needcomma=true;
749             if (cn.getSuperDesc()!=null) {
750                 ClassDescriptor cdsuper=cn.getSuperDesc();
751                 output.print(cdsuper.getId());
752             } else
753                 output.print("-1");
754         }
755         output.println("};");
756     }
757
758     /** Force consistent field ordering between inherited classes. */
759
760     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
761         ClassDescriptor sp=cn.getSuperDesc();
762         if (sp!=null)
763             printClassStruct(sp, classdefout);
764         
765         if (!fieldorder.containsKey(cn)) {
766             Vector fields=new Vector();
767             fieldorder.put(cn,fields);
768             Iterator fieldit=cn.getFields();
769             while(fieldit.hasNext()) {
770                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
771                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
772                     fields.add(fd);
773             }
774         }
775         Vector fields=(Vector)fieldorder.get(cn);
776
777         for(int i=0;i<fields.size();i++) {
778             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
779             if (fd.getType().isClass()||fd.getType().isArray())
780                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
781             else 
782                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
783         }
784     }
785
786
787     /* Map flags to integers consistently between inherited
788      * classes. */
789
790     private void mapFlags(ClassDescriptor cn) {
791         ClassDescriptor sp=cn.getSuperDesc();
792         if (sp!=null)
793             mapFlags(sp);
794         int max=0;
795         if (!flagorder.containsKey(cn)) {
796             Hashtable flags=new Hashtable();
797             flagorder.put(cn,flags);
798             if (sp!=null) {
799                 Hashtable superflags=(Hashtable)flagorder.get(sp);
800                 Iterator superflagit=superflags.keySet().iterator();
801                 while(superflagit.hasNext()) {
802                     FlagDescriptor fd=(FlagDescriptor)superflagit.next();
803                     Integer number=(Integer)superflags.get(fd);
804                     flags.put(fd, number);
805                     if ((number.intValue()+1)>max)
806                         max=number.intValue()+1;
807                 }
808             }
809             
810             Iterator flagit=cn.getFlags();
811             while(flagit.hasNext()) {
812                 FlagDescriptor fd=(FlagDescriptor)flagit.next();
813                 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
814                     flags.put(fd, new Integer(max++));
815             }
816         }
817     }
818
819
820     /** This function outputs (1) structures that parameters are
821      * passed in (when PRECISE GC is enabled) and (2) function
822      * prototypes for the methods */
823
824     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
825         /* Output class structure */
826         classdefout.println("struct "+cn.getSafeSymbol()+" {");
827         classdefout.println("  int type;");
828         if (state.THREAD) {
829             classdefout.println("  pthread_t tid;");
830             classdefout.println("  void * lockentry;");
831             classdefout.println("  int lockcount;");
832         }
833
834         if (state.TASK) {
835             classdefout.println("  int flag;");
836             classdefout.println("  void * flagptr;");
837             if (state.OPTIONAL) classdefout.println("  int failedstatus;");
838         }
839         printClassStruct(cn, classdefout);
840         classdefout.println("};\n");
841
842         /* Cycle through methods */
843         Iterator methodit=cn.getMethods();
844         while(methodit.hasNext()) {
845             /* Classify parameters */
846             MethodDescriptor md=(MethodDescriptor)methodit.next();
847             FlatMethod fm=state.getMethodFlat(md);
848             generateTempStructs(fm);
849
850             ParamsObject objectparams=(ParamsObject) paramstable.get(md);
851             TempObject objecttemps=(TempObject) tempstable.get(md);
852
853             /* Output parameter structure */
854             if (GENERATEPRECISEGC) {
855                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
856                 output.println("  int size;");
857                 output.println("  void * next;");
858                 for(int i=0;i<objectparams.numPointers();i++) {
859                     TempDescriptor temp=objectparams.getPointer(i);
860                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
861                 }
862                 output.println("};\n");
863             }
864
865             /* Output temp structure */
866             if (GENERATEPRECISEGC) {
867                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
868                 output.println("  int size;");
869                 output.println("  void * next;");
870                 for(int i=0;i<objecttemps.numPointers();i++) {
871                     TempDescriptor temp=objecttemps.getPointer(i);
872                     if (temp.getType().isNull())
873                         output.println("  void * "+temp.getSafeSymbol()+";");
874                     else
875                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
876                 }
877                 output.println("};\n");
878             }
879             
880             /* Output method declaration */
881             if (md.getReturnType()!=null) {
882                 if (md.getReturnType().isClass()||md.getReturnType().isArray())
883                     headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
884                 else
885                     headersout.print(md.getReturnType().getSafeSymbol()+" ");
886             } else 
887                 //catch the constructor case
888                 headersout.print("void ");
889             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
890             
891             boolean printcomma=false;
892             if (GENERATEPRECISEGC) {
893                 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
894                 printcomma=true;
895             }
896
897             //output parameter list
898             for(int i=0;i<objectparams.numPrimitives();i++) {
899                 TempDescriptor temp=objectparams.getPrimitive(i);
900                 if (printcomma)
901                     headersout.print(", ");
902                 printcomma=true;
903                 if (temp.getType().isClass()||temp.getType().isArray())
904                     headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
905                 else
906                     headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
907             }
908             headersout.println(");\n");
909         }
910     }
911
912
913     /** This function outputs (1) structures that parameters are
914      * passed in (when PRECISE GC is enabled) and (2) function
915      * prototypes for the tasks */
916
917     private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
918         /* Cycle through tasks */
919         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
920
921         while(taskit.hasNext()) {
922             /* Classify parameters */
923             TaskDescriptor task=(TaskDescriptor)taskit.next();
924             FlatMethod fm=state.getMethodFlat(task);
925             generateTempStructs(fm);
926
927             ParamsObject objectparams=(ParamsObject) paramstable.get(task);
928             TempObject objecttemps=(TempObject) tempstable.get(task);
929
930             /* Output parameter structure */
931             if (GENERATEPRECISEGC) {
932                 output.println("struct "+task.getSafeSymbol()+"_params {");
933
934                 output.println("  int size;");
935                 output.println("  void * next;");
936                 for(int i=0;i<objectparams.numPointers();i++) {
937                     TempDescriptor temp=objectparams.getPointer(i);
938                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
939                 }
940
941                 output.println("};\n");
942                 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
943                     maxtaskparams=objectparams.numPointers()+fm.numTags();
944                 }
945             }
946
947             /* Output temp structure */
948             if (GENERATEPRECISEGC) {
949                 output.println("struct "+task.getSafeSymbol()+"_locals {");
950                 output.println("  int size;");
951                 output.println("  void * next;");
952                 for(int i=0;i<objecttemps.numPointers();i++) {
953                     TempDescriptor temp=objecttemps.getPointer(i);
954                     if (temp.getType().isNull())
955                         output.println("  void * "+temp.getSafeSymbol()+";");
956                     else if(temp.getType().isTag())
957                         output.println("  struct "+
958                                        (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
959                     else
960                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
961                 }
962                 output.println("};\n");
963             }
964             
965             /* Output task declaration */
966             headersout.print("void " + task.getSafeSymbol()+"(");
967             
968             boolean printcomma=false;
969             if (GENERATEPRECISEGC) {
970                 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
971             } else
972                 headersout.print("void * parameterarray[]");
973             headersout.println(");\n");
974         }
975     }
976
977     /** Generate code for FlatMethod fm. */
978
979     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
980         MethodDescriptor md=fm.getMethod();
981         TaskDescriptor task=fm.getTask();
982
983         ClassDescriptor cn=md!=null?md.getClassDesc():null;
984
985         ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
986
987         generateHeader(fm, md!=null?md:task,output);
988
989         TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
990
991         /* Print code */
992         if (GENERATEPRECISEGC) {
993             if (md!=null)
994                 output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
995             else
996                 output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
997
998             output.print(objecttemp.numPointers()+",");
999             output.print(paramsprefix);
1000             for(int j=0;j<objecttemp.numPointers();j++)
1001                 output.print(", NULL");
1002             output.println("};");
1003         }
1004
1005         for(int i=0;i<objecttemp.numPrimitives();i++) {
1006             TempDescriptor td=objecttemp.getPrimitive(i);
1007             TypeDescriptor type=td.getType();
1008             if (type.isNull())
1009                 output.println("   void * "+td.getSafeSymbol()+";");
1010             else if (type.isClass()||type.isArray())
1011                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1012             else
1013                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1014         }
1015
1016         /* Generate labels first */
1017         HashSet tovisit=new HashSet();
1018         HashSet visited=new HashSet();
1019         int labelindex=0;
1020         Hashtable nodetolabel=new Hashtable();
1021         tovisit.add(fm.getNext(0));
1022         FlatNode current_node=null;
1023
1024         //Assign labels 1st
1025         //Node needs a label if it is
1026         while(!tovisit.isEmpty()) {
1027             FlatNode fn=(FlatNode)tovisit.iterator().next();
1028             tovisit.remove(fn);
1029             visited.add(fn);
1030             for(int i=0;i<fn.numNext();i++) {
1031                 FlatNode nn=fn.getNext(i);
1032                 if(i>0) {
1033                     //1) Edge >1 of node
1034                     nodetolabel.put(nn,new Integer(labelindex++));
1035                 }
1036                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1037                     tovisit.add(nn);
1038                 } else {
1039                     //2) Join point
1040                     nodetolabel.put(nn,new Integer(labelindex++));
1041                 }
1042             }
1043         }
1044
1045         if (state.THREAD&&GENERATEPRECISEGC) {
1046             output.println("checkcollect(&"+localsprefix+");");
1047         }
1048         
1049         //Do the actual code generation
1050         tovisit=new HashSet();
1051         visited=new HashSet();
1052         tovisit.add(fm.getNext(0));
1053         while(current_node!=null||!tovisit.isEmpty()) {
1054             if (current_node==null) {
1055                 current_node=(FlatNode)tovisit.iterator().next();
1056                 tovisit.remove(current_node);
1057             }
1058             visited.add(current_node);
1059             if (nodetolabel.containsKey(current_node))
1060                 output.println("L"+nodetolabel.get(current_node)+":");
1061             if (state.INSTRUCTIONFAILURE) {
1062                 if (state.THREAD) {
1063                     output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1064                 }
1065                 else
1066                     output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1067             }
1068             if (current_node.numNext()==0) {
1069                 output.print("   ");
1070                 generateFlatNode(fm, current_node, output);
1071                 if (current_node.kind()!=FKind.FlatReturnNode) {
1072                     output.println("   return;");
1073                 }
1074                 current_node=null;
1075             } else if(current_node.numNext()==1) {
1076                 output.print("   ");
1077                 generateFlatNode(fm, current_node, output);
1078                 FlatNode nextnode=current_node.getNext(0);
1079                 if (visited.contains(nextnode)) {
1080                     output.println("goto L"+nodetolabel.get(nextnode)+";");
1081                     current_node=null;
1082                 } else
1083                     current_node=nextnode;
1084             } else if (current_node.numNext()==2) {
1085                 /* Branch */
1086                 output.print("   ");
1087                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1088                 if (!visited.contains(current_node.getNext(1)))
1089                     tovisit.add(current_node.getNext(1));
1090                 if (visited.contains(current_node.getNext(0))) {
1091                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1092                     current_node=null;
1093                 } else
1094                     current_node=current_node.getNext(0);
1095             } else throw new Error();
1096         }
1097
1098
1099         output.println("}\n\n");
1100     }
1101
1102     /** Generate text string that corresponds to the Temp td. */
1103     private String generateTemp(FlatMethod fm, TempDescriptor td) {
1104         MethodDescriptor md=fm.getMethod();
1105         TaskDescriptor task=fm.getTask();
1106         TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
1107
1108         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1109             return td.getSafeSymbol();
1110         }
1111
1112         if (objecttemps.isLocalPtr(td)) {
1113             return localsprefix+"."+td.getSafeSymbol();
1114         }
1115
1116         if (objecttemps.isParamPtr(td)) {
1117             return paramsprefix+"->"+td.getSafeSymbol();
1118         }
1119         throw new Error();
1120     }
1121
1122     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
1123         switch(fn.kind()) {
1124         case FKind.FlatAtomicEnterNode:
1125             generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
1126             return;
1127         case FKind.FlatAtomicExitNode:
1128             generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
1129             return;
1130         case FKind.FlatTagDeclaration:
1131             generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1132             return;
1133         case FKind.FlatCall:
1134             generateFlatCall(fm, (FlatCall) fn,output);
1135             return;
1136         case FKind.FlatFieldNode:
1137             generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
1138             return;
1139         case FKind.FlatElementNode:
1140             generateFlatElementNode(fm, (FlatElementNode) fn,output);
1141             return;
1142         case FKind.FlatSetElementNode:
1143             generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1144             return;
1145         case FKind.FlatSetFieldNode:
1146             generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
1147             return;
1148         case FKind.FlatNew:
1149             generateFlatNew(fm, (FlatNew) fn,output);
1150             return;
1151         case FKind.FlatOpNode:
1152             generateFlatOpNode(fm, (FlatOpNode) fn,output);
1153             return;
1154         case FKind.FlatCastNode:
1155             generateFlatCastNode(fm, (FlatCastNode) fn,output);
1156             return;
1157         case FKind.FlatLiteralNode:
1158             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1159             return;
1160         case FKind.FlatReturnNode:
1161             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1162             return;
1163         case FKind.FlatNop:
1164             output.println("/* nop */");
1165             return;
1166         case FKind.FlatBackEdge:
1167             if (state.THREAD&&GENERATEPRECISEGC) {
1168                 output.println("checkcollect(&"+localsprefix+");");
1169             } else
1170                 output.println("/* nop */");
1171             return;
1172         case FKind.FlatCheckNode:
1173             generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1174             return;
1175         case FKind.FlatFlagActionNode:
1176             generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1177             return;
1178         }
1179         throw new Error();
1180
1181     }
1182     
1183     public void generateFlatAtomicEnterNode(FlatMethod fm,  FlatAtomicEnterNode faen, PrintWriter output) {
1184     }
1185
1186     public void generateFlatAtomicExitNode(FlatMethod fm,  FlatAtomicExitNode faen, PrintWriter output) {
1187     }
1188
1189     private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
1190         if (state.CONSCHECK) {
1191             String specname=fcn.getSpec();
1192             String varname="repairstate___";
1193             output.println("{");
1194             output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1195
1196             TempDescriptor[] temps=fcn.getTemps();
1197             String[] vars=fcn.getVars();
1198             for(int i=0;i<temps.length;i++) {
1199                 output.println(varname+"->"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";");
1200             }
1201
1202             output.println("if (doanalysis"+specname+"("+varname+")) {");
1203             output.println("free"+specname+"_state("+varname+");");
1204             output.println("} else {");
1205             output.println("/* Bad invariant */");
1206             output.println("free"+specname+"_state("+varname+");");
1207             output.println("abort_task();");
1208             output.println("}");
1209             output.println("}");
1210         }
1211     }
1212
1213     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1214         MethodDescriptor md=fc.getMethod();
1215         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1216         ClassDescriptor cn=md.getClassDesc();
1217         output.println("{");
1218         if (GENERATEPRECISEGC) {
1219             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1220             
1221             output.print(objectparams.numPointers());
1222             //      output.print(objectparams.getUID());
1223             output.print(", & "+localsprefix);
1224             if (fc.getThis()!=null) {
1225                 output.print(", ");
1226                 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
1227             }
1228             for(int i=0;i<fc.numArgs();i++) {
1229                 Descriptor var=md.getParameter(i);
1230                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1231                 if (objectparams.isParamPtr(paramtemp)) {
1232                     TempDescriptor targ=fc.getArg(i);
1233                     output.print(", ");
1234                     TypeDescriptor td=md.getParamType(i);
1235                     if (td.isTag())
1236                         output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1237                     else
1238                         output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1239                 }
1240             }
1241             output.println("};");
1242         }
1243         output.print("       ");
1244
1245
1246         if (fc.getReturnTemp()!=null)
1247             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1248
1249         /* Do we need to do virtual dispatch? */
1250         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1251             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1252         } else {
1253             
1254             output.print("((");
1255             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1256                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1257             else
1258                 output.print(md.getReturnType().getSafeSymbol()+" ");
1259             output.print("(*)(");
1260
1261             boolean printcomma=false;
1262             if (GENERATEPRECISEGC) {
1263                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1264                 printcomma=true;
1265             } 
1266
1267
1268             for(int i=0;i<objectparams.numPrimitives();i++) {
1269                 TempDescriptor temp=objectparams.getPrimitive(i);
1270                 if (printcomma)
1271                     output.print(", ");
1272                 printcomma=true;
1273                 if (temp.getType().isClass()||temp.getType().isArray())
1274                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1275                 else
1276                     output.print(temp.getType().getSafeSymbol());
1277             }
1278
1279             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1280         }
1281
1282         output.print("(");
1283         boolean needcomma=false;
1284         if (GENERATEPRECISEGC) {
1285             output.print("&__parameterlist__");
1286             needcomma=true;
1287         } else {
1288             if (fc.getThis()!=null) {
1289                 TypeDescriptor ptd=md.getThis().getType();
1290                 if (ptd.isClass()&&!ptd.isArray())
1291                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1292                 output.print(generateTemp(fm,fc.getThis()));
1293                 needcomma=true;
1294             }
1295         }
1296         for(int i=0;i<fc.numArgs();i++) {
1297             Descriptor var=md.getParameter(i);
1298             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1299             if (objectparams.isParamPrim(paramtemp)) {
1300                 TempDescriptor targ=fc.getArg(i);
1301                 if (needcomma)
1302                     output.print(", ");
1303
1304                 TypeDescriptor ptd=md.getParamType(i);
1305                 if (ptd.isClass()&&!ptd.isArray())
1306                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1307                 output.print(generateTemp(fm, targ));
1308                 needcomma=true;
1309             }
1310         }
1311         output.println(");");
1312         output.println("   }");
1313     }
1314
1315     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1316         Set subclasses=typeutil.getSubClasses(thiscd);
1317         if (subclasses==null)
1318             return true;
1319         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1320             ClassDescriptor cd=(ClassDescriptor)classit.next();
1321             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1322             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1323                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1324                 if (md.matches(matchmd))
1325                     return false;
1326             }
1327         }
1328         return true;
1329     }
1330
1331     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
1332         output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1333     }
1334
1335     private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
1336         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1337             throw new Error("Can't set array length");
1338         output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1339     }
1340
1341     private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1342         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1343         String type="";
1344
1345         if (elementtype.isArray()||elementtype.isClass())
1346             type="void *";
1347         else 
1348             type=elementtype.getSafeSymbol()+" ";
1349
1350         if (fen.needsBoundsCheck()) {
1351             output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1352             output.println("failedboundschk();");
1353         }
1354
1355         output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1356     }
1357
1358     private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1359         //TODO: need dynamic check to make sure this assignment is actually legal
1360         //Because Object[] could actually be something more specific...ie. Integer[]
1361
1362         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1363         String type="";
1364
1365         if (elementtype.isArray()||elementtype.isClass())
1366             type="void *";
1367         else 
1368             type=elementtype.getSafeSymbol()+" ";
1369
1370         if (fsen.needsBoundsCheck()) {
1371             output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1372             output.println("failedboundschk();");
1373         }
1374
1375         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1376     }
1377
1378     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1379         if (fn.getType().isArray()) {
1380             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1381             if (GENERATEPRECISEGC) {
1382                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1383             } else {
1384                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1385             }
1386         } else {
1387             if (GENERATEPRECISEGC) {
1388                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1389             } else {
1390                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1391             }
1392         }
1393     }
1394
1395
1396     private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
1397         if (GENERATEPRECISEGC) {
1398             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1399         } else {
1400             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
1401         }
1402     }
1403
1404     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1405
1406         if (fon.getRight()!=null)
1407             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1408         else if (fon.getOp().getOp()==Operation.ASSIGN)
1409             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1410         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1411             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1412         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1413             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1414         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1415             output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1416         else
1417             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1418     }
1419
1420     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1421         /* TODO: Do type check here */
1422         if (fcn.getType().isArray()) {
1423             throw new Error();
1424         } else if (fcn.getType().isClass())
1425             output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
1426         else
1427             output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1428     }
1429
1430     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1431         if (fln.getValue()==null)
1432             output.println(generateTemp(fm, fln.getDst())+"=0;");
1433         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1434             if (GENERATEPRECISEGC) {
1435                 output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1436             } else {
1437                 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1438             }
1439         } else if (fln.getType().isBoolean()) {
1440             if (((Boolean)fln.getValue()).booleanValue())
1441                 output.println(generateTemp(fm, fln.getDst())+"=1;");
1442             else
1443                 output.println(generateTemp(fm, fln.getDst())+"=0;");
1444         } else if (fln.getType().isChar()) {
1445             String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1446             output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1447         } else
1448             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1449     }
1450
1451     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1452         if (frn.getReturnTemp()!=null)
1453             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1454         else
1455             output.println("return;");
1456     }
1457
1458     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1459         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1460     }
1461
1462     /** This method generates header information for the method or
1463      * task referenced by the Descriptor des. */
1464
1465     private void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
1466         /* Print header */
1467         ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1468         MethodDescriptor md=null;
1469         TaskDescriptor task=null;
1470         if (des instanceof MethodDescriptor)
1471             md=(MethodDescriptor) des;
1472         else
1473             task=(TaskDescriptor) des;
1474
1475         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1476         
1477         if (md!=null&&md.getReturnType()!=null) {
1478             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1479                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1480             else
1481                 output.print(md.getReturnType().getSafeSymbol()+" ");
1482         } else 
1483             //catch the constructor case
1484             output.print("void ");
1485         if (md!=null)
1486             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1487         else
1488             output.print(task.getSafeSymbol()+"(");
1489         
1490         boolean printcomma=false;
1491         if (GENERATEPRECISEGC) {
1492             if (md!=null)
1493                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1494             else
1495                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1496             printcomma=true;
1497         }
1498
1499         if (md!=null) {
1500             /* Method */
1501             for(int i=0;i<objectparams.numPrimitives();i++) {
1502                 TempDescriptor temp=objectparams.getPrimitive(i);
1503                 if (printcomma)
1504                     output.print(", ");
1505                 printcomma=true;
1506                 if (temp.getType().isClass()||temp.getType().isArray())
1507                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1508                 else
1509                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1510             }
1511             output.println(") {");
1512         } else if (!GENERATEPRECISEGC) {
1513             /* Imprecise Task */
1514             output.println("void * parameterarray[]) {");
1515             /* Unpack variables */
1516             for(int i=0;i<objectparams.numPrimitives();i++) {
1517                 TempDescriptor temp=objectparams.getPrimitive(i);
1518                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1519             }
1520             for(int i=0;i<fm.numTags();i++) {
1521                 TempDescriptor temp=fm.getTag(i);
1522                 int offset=i+objectparams.numPrimitives();
1523                 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1524             }
1525
1526             if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1527                 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1528         } else output.println(") {");
1529     }
1530     
1531     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1532         output.println("/* FlatFlagActionNode */");
1533
1534
1535         /* Process tag changes */
1536         Relation tagsettable=new Relation();
1537         Relation tagcleartable=new Relation();
1538
1539         Iterator tagsit=ffan.getTempTagPairs(); 
1540         while (tagsit.hasNext()) {
1541             TempTagPair ttp=(TempTagPair) tagsit.next();
1542             TempDescriptor objtmp=ttp.getTemp();
1543             TagDescriptor tag=ttp.getTag();
1544             TempDescriptor tagtmp=ttp.getTagTemp();
1545             boolean tagstatus=ffan.getTagChange(ttp);
1546             if (tagstatus) {
1547                 tagsettable.put(objtmp, tagtmp);
1548             } else {
1549                 tagcleartable.put(objtmp, tagtmp);
1550             }
1551         }
1552
1553
1554         Hashtable flagandtable=new Hashtable();
1555         Hashtable flagortable=new Hashtable();
1556
1557         /* Process flag changes */
1558         Iterator flagsit=ffan.getTempFlagPairs();
1559         while(flagsit.hasNext()) {
1560             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1561             TempDescriptor temp=tfp.getTemp();
1562             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1563             FlagDescriptor flag=tfp.getFlag();
1564             if (flag==null) {
1565                 //Newly allocate objects that don't set any flags case
1566                 if (flagortable.containsKey(temp)) {
1567                     throw new Error();
1568                 }
1569                 int mask=0;
1570                 flagortable.put(temp,new Integer(mask));
1571             } else {
1572                 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1573                 boolean flagstatus=ffan.getFlagChange(tfp);
1574                 if (flagstatus) {
1575                     int mask=0;
1576                     if (flagortable.containsKey(temp)) {
1577                         mask=((Integer)flagortable.get(temp)).intValue();
1578                     }
1579                     mask|=flagid;
1580                     flagortable.put(temp,new Integer(mask));
1581                 } else {
1582                     int mask=0xFFFFFFFF;
1583                     if (flagandtable.containsKey(temp)) {
1584                         mask=((Integer)flagandtable.get(temp)).intValue();
1585                     }
1586                     mask&=(0xFFFFFFFF^flagid);
1587                     flagandtable.put(temp,new Integer(mask));
1588                 }
1589             }
1590         }
1591
1592
1593         HashSet flagtagset=new HashSet();
1594         flagtagset.addAll(flagortable.keySet());
1595         flagtagset.addAll(flagandtable.keySet());
1596         flagtagset.addAll(tagsettable.keySet());
1597         flagtagset.addAll(tagcleartable.keySet());
1598
1599         Iterator ftit=flagtagset.iterator();
1600         while(ftit.hasNext()) {
1601             TempDescriptor temp=(TempDescriptor)ftit.next();
1602             
1603             
1604             Set tagtmps=tagcleartable.get(temp);
1605             if (tagtmps!=null) {
1606                 Iterator tagit=tagtmps.iterator();
1607                 while(tagit.hasNext()) {
1608                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1609                     if (GENERATEPRECISEGC) 
1610                         output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1611                     else
1612                         output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1613                 }
1614             }
1615
1616             tagtmps=tagsettable.get(temp);
1617             if (tagtmps!=null) {
1618                 Iterator tagit=tagtmps.iterator();
1619                 while(tagit.hasNext()) {
1620                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1621                     if (GENERATEPRECISEGC)
1622                         output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1623                     else
1624                         output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1625                 }
1626             }
1627
1628             int ormask=0;
1629             int andmask=0xFFFFFFF;
1630             
1631             if (flagortable.containsKey(temp))
1632                 ormask=((Integer)flagortable.get(temp)).intValue();
1633             if (flagandtable.containsKey(temp))
1634                 andmask=((Integer)flagandtable.get(temp)).intValue();
1635             if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1636                 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1637             } else {
1638                 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1639             }
1640         }
1641     }
1642
1643      void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
1644          
1645          //GENERATE HEADERS
1646          headers.println("#include \"task.h\"\n\n");
1647          
1648
1649          
1650          //STRUCT PREDICATEMEMBER
1651          headers.println("struct predicatemember{");
1652          headers.println("int type;");
1653          headers.println("int numdnfterms;");
1654          headers.println("int * flags;");
1655          headers.println("int numtags;");
1656          headers.println("int * tags;\n};\n\n");
1657
1658          //STRUCT EXITFLAGSTATE
1659          headers.println("struct exitflagstate{");
1660          headers.println("int numflags;");
1661          headers.println("int * flags;");
1662          /*
1663            headers.println("int numtags;");
1664            headers.println("int * tags;");
1665          */
1666          headers.println("\n};\n\n");
1667          
1668          //STRUCT EXITSTATES
1669          headers.println("struct exitstates{");
1670          headers.println("int numexitflagstates;");
1671          headers.println("struct exitflagstate * exitflagstatearray;\n};\n\n");
1672
1673          //STRUCT OPTIONALTASKDESCRIPTOR
1674          headers.println("struct optionaltaskdescriptor{");
1675          headers.println("struct taskdescriptor * task;");
1676          headers.println("int numpredicatemembers;");
1677          headers.println("struct predicatemember * predicatememberarray;");
1678          headers.println("int numexitstates;");
1679          headers.println("struct existates * exitstatesarray;\n};\n\n");
1680                  
1681          //STRUCT FSANALYSISWRAPPER
1682          headers.println("struct fsanalysiswrapper{");
1683          headers.println("int numflags;");
1684          headers.println("int * flags;");
1685          headers.println("int numtags;");
1686          headers.println("int * tags;");
1687          headers.println("int numoptionaltaskdescriptors;");
1688          headers.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray;\n};\n\n");
1689
1690          //STRUCT CLASSANALYSISWRAPPER
1691          headers.println("struct classanalyiswrapper{");
1692          headers.println("int type;");
1693          headers.println("int numfsanalysiswrappers;");
1694          headers.println("struct fsanalysiswrapper * fsanalysiswrapperarray;\n};\n\n");
1695
1696          Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1697          while(taskit.hasNext()) {
1698              TaskDescriptor td=(TaskDescriptor)taskit.next();
1699              headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
1700          }
1701          
1702                                                    
1703          
1704          //GENERATE STRUCTS
1705          output.println("#include \"optionalstruct.h\"\n\n");    
1706          HashSet processedcd = new HashSet();
1707         
1708
1709          Enumeration e = safeexecution.keys();
1710          while (e.hasMoreElements()) {
1711              
1712              //get the class
1713              ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1714              Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
1715              
1716              //Generate the struct of optionals
1717              if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
1718              Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
1719              if( !c_otd.isEmpty() ){
1720                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
1721                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
1722                      
1723                      //generate the int arrays for the predicate
1724                      Predicate predicate = otd.predicate;
1725                      int predicateindex = 0;
1726                      //iterate through the classes concerned by the predicate
1727                      Collection c_vard = predicate.vardescriptors.values();
1728                      for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
1729                          VarDescriptor vard = (VarDescriptor)vard_it.next();
1730                          TypeDescriptor typed = vard.getType();
1731                          
1732                          //generate for flags
1733                          HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
1734                          output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1735                          int numberterms=0;
1736                          if (fen_hashset!=null){
1737                              for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
1738                                  FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
1739                                  if (fen==null) {
1740                                      //output.println("0x0, 0x0 };");
1741                                      //numberterms+=1;
1742                                  }
1743                                  else {
1744                                      
1745                                      DNFFlag dflag=fen.getDNF();
1746                                      numberterms+=dflag.size();
1747                                      
1748                                      Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
1749                                      
1750                                      for(int j=0;j<dflag.size();j++) {
1751                                          if (j!=0)
1752                                              output.println(",");
1753                                          Vector term=dflag.get(j);
1754                                          int andmask=0;
1755                                          int checkmask=0;
1756                                          for(int k=0;k<term.size();k++) {
1757                                              DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
1758                                              FlagDescriptor fd=dfa.getFlag();
1759                                              boolean negated=dfa.getNegated();
1760                                              int flagid=1<<((Integer)flags.get(fd)).intValue();
1761                                              andmask|=flagid;
1762                                              if (!negated)
1763                                                  checkmask|=flagid;
1764                                          }
1765                                          output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
1766                                      }
1767                                  }
1768                              }
1769                          }
1770                          output.println("};\n");
1771                          
1772                          //generate for tags
1773                          TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
1774                          output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1775                          //BUG...added next line to fix, test with any task program
1776                          int numtags = 0;
1777                          if (tagel!=null){
1778                              for(int j=0;j<tagel.numTags();j++) {
1779                                  if (j!=0)
1780                                      output.println(",");
1781                                  /* for each tag we need */
1782                                  /* which slot it is */
1783                                  /* what type it is */
1784                                  //TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(tagel.getName(j));
1785                                  TempDescriptor tmp=tagel.getTemp(j);
1786                                  //got rid of slot
1787                                  output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
1788                              }
1789                              numtags = tagel.numTags();
1790                          }
1791                          output.println("};");
1792                          
1793                          //store the result into a predicatemember struct
1794                          output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1795                          output.println("/*type*/"+typed.getClassDesc().getId()+",");
1796                          output.println("/* number of dnf terms */"+numberterms+",");
1797                          output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1798                          output.println("/* number of tag */"+numtags+",");
1799                          output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1800                          output.println("};\n");
1801                          predicateindex++;
1802                      }
1803                      
1804
1805                      //generate an array that stores the entire predicate
1806                      output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1807                      for( int j = 0; j<predicateindex; j++){
1808                          if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1809                          else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1810                      }
1811
1812                      //generate the struct for possible exitfses
1813                      HashSet<HashSet> exitfses = otd.exitfses;
1814                      int exitindex = 0;
1815                      int nbexit = exitfses.size();
1816                      int fsnumber;
1817                      
1818                      //iterate through possible exits
1819                      for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
1820                          HashSet temp_hashset = (HashSet)exitfseshash.next();
1821                          fsnumber = 0 ;
1822                          
1823                          //iterate through possible FSes corresponding to the exit
1824                          for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
1825                             FlagState fs = (FlagState)exfses.next();
1826                             fsnumber++;
1827                             output.println("int flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1828                             int counterflag = 0;
1829                             for(Iterator flags = fs.getFlags(); flags.hasNext();){
1830                                 FlagDescriptor flagd = (FlagDescriptor)flags.next();
1831                                 int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
1832                                 if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
1833                                 else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
1834                                 counterflag++;
1835                             } 
1836                             output.println("};\n");
1837                             //do the same for tags;
1838                             //maybe not needed because no tag changes tolerated.
1839
1840                             //store the information into a struct
1841                             output.println("struct exitflagstate exitflagstate"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1842                             output.println("/*number of flags*/"+counterflag+",");
1843                             output.println("flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1844                             output.println("};\n");
1845                          }
1846                          
1847                          //store fses corresponding to this exit into an array
1848                          output.println("struct exitflagstate * exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+" [] = {");
1849                          for( int j = 0; j<fsnumber; j++){
1850                              if( j != fsnumber-1)output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"'");
1851                              else output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1852                          }
1853                          
1854                          //store that information in a struct
1855                          output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1856                          output.println("/*number of exitflagstate*/"+fsnumber+",");
1857                          output.println("exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1858                          output.println("};\n");
1859
1860                          exitindex++;
1861                      }
1862                      
1863                      //store the information concerning all exits into an array
1864                      output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1865                      for( int j = 0; j<nbexit; j++){
1866                          if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1867                          else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1868                      }
1869                                      
1870                                      
1871                      //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
1872                      output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1873                      output.println("task_"+otd.td.getSafeSymbol()+",");
1874                      output.println("/*number of members */"+predicateindex+",");
1875                      output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1876                      output.println("/*number of exit fses */"+nbexit+",");
1877                      output.println("exitstatearray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1878                      output.println("};\n");
1879                  }      
1880              }
1881              else continue; // if there is no optionals, there is no need to build the rest of the struct 
1882              
1883              //get all the possible falgstates reachable by an object
1884              Hashtable hashtbtemp = safeexecution.get(cdtemp);
1885              Enumeration fses = hashtbtemp.keys();
1886              int fscounter = 0;
1887              while(fses.hasMoreElements()){
1888                  FlagState fs = (FlagState)fses.nextElement();
1889                  fscounter++;
1890                  
1891                  //get the set of OptionalTaskDescriptors corresponding
1892                  HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
1893                  //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
1894                  
1895                  output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
1896                  for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
1897                      OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
1898                      if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1899                      
1900                      else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1901                  }
1902
1903                  //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
1904                  
1905                  output.println("int flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
1906                  for(Iterator flags = fs.getFlags(); flags.hasNext();){
1907                      FlagDescriptor flagd = (FlagDescriptor)flags.next();
1908                      int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
1909                      if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
1910                      else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
1911                      
1912                  }
1913                  //process tag information
1914                  
1915                  int tagcounter = 0;
1916                  //TagExpressionList tagel = fs.getTags(); 
1917                  //output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1918                  //BUG...added next line to fix, test with any task program
1919                  
1920                  //if (tagel!=null){
1921                  //    for(int j=0;j<tagel.numTags();j++) {
1922                  //      if (j!=0)
1923                  //          output.println(",");
1924                  //      TempDescriptor tmp=tagel.getTemp(j);
1925                  //      output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
1926                  //   }
1927                  //  numtags = tagel.numTags();
1928                  //}
1929                  //output.println("};");
1930                  
1931                  
1932                  //Store the result in fsanalysiswrapper
1933                  output.println("};\n");
1934                  output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
1935                  output.println("/* number of flags*/"+fs.numFlags()+",");
1936                  output.println("flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
1937                  output.println("/* number of tags*/"+tagcounter+",");
1938                  output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
1939                  output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
1940                  output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
1941                  output.println("};\n");
1942                  
1943              }
1944
1945              //Build the array of fsanalysiswrappers
1946              output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
1947              for(int i = 0; i<fscounter; i++){
1948                  if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
1949                          
1950                      else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
1951              }
1952
1953              //Build the classanalysiswrapper referring to the previous array
1954              output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
1955              output.println("/*type*/"+cdtemp.getId()+",");
1956              output.println("/* number of fsanalysiswrappers */"+fscounter+",");
1957              output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
1958              fscounter = 0;
1959              processedcd.add(cdtemp);
1960          }
1961
1962          //build an array containing every classes for which code has been build
1963          output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
1964          for(Iterator classit = processedcd.iterator(); classit.hasNext();){
1965              ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
1966              if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
1967              else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
1968          }
1969          output.println("int numclasses = "+processedcd.size()+";");
1970          
1971      }
1972     
1973 }
1974          
1975
1976
1977
1978
1979