7a123a216750f79bbdefe2b8a8f66ef6634e2da0
[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.*;
6 import java.util.*;
7 import java.io.*;
8
9 public class BuildCode {
10     State state;
11     Hashtable temptovar;
12     Hashtable paramstable;
13     Hashtable tempstable;
14     Hashtable fieldorder;
15     Hashtable flagorder;
16     int tag=0;
17     String localsprefix="___locals___";
18     String paramsprefix="___params___";
19     public static boolean GENERATEPRECISEGC=false;
20     public static String PREFIX="";
21     public static String arraytype="ArrayObject";
22     Virtual virtualcalls;
23     TypeUtil typeutil;
24     private int maxtaskparams=0;
25     ClassDescriptor[] cdarray;
26     TypeDescriptor[] arraytable;
27
28     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
29         state=st;
30         this.temptovar=temptovar;
31         paramstable=new Hashtable();    
32         tempstable=new Hashtable();
33         fieldorder=new Hashtable();
34         flagorder=new Hashtable();
35         this.typeutil=typeutil;
36         virtualcalls=new Virtual(state);
37     }
38
39     /** The buildCode method outputs C code for all the methods.  The Flat
40      * versions of the methods must already be generated and stored in
41      * the State object. */
42
43     public void buildCode() {
44         /* Create output streams to write to */
45         PrintWriter outclassdefs=null;
46         PrintWriter outstructs=null;
47         PrintWriter outrepairstructs=null;
48         PrintWriter outmethodheader=null;
49         PrintWriter outmethod=null;
50         PrintWriter outvirtual=null;
51         PrintWriter outtask=null;
52         PrintWriter outtaskdefs=null;
53
54         try {
55             OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
56             outstructs=new java.io.PrintWriter(str, true);
57             str=new FileOutputStream(PREFIX+"methodheaders.h");
58             outmethodheader=new java.io.PrintWriter(str, true);
59             str=new FileOutputStream(PREFIX+"classdefs.h");
60             outclassdefs=new java.io.PrintWriter(str, true);
61             str=new FileOutputStream(PREFIX+"methods.c");
62             outmethod=new java.io.PrintWriter(str, true);
63             str=new FileOutputStream(PREFIX+"virtualtable.h");
64             outvirtual=new java.io.PrintWriter(str, true);
65             if (state.TASK) {
66                 str=new FileOutputStream(PREFIX+"task.h");
67                 outtask=new java.io.PrintWriter(str, true);
68                 str=new FileOutputStream(PREFIX+"taskdefs.c");
69                 outtaskdefs=new java.io.PrintWriter(str, true);
70             }
71             if (state.structfile!=null) {
72                 str=new FileOutputStream(PREFIX+state.structfile+".struct");
73                 outrepairstructs=new java.io.PrintWriter(str, true);
74             }
75         } catch (Exception e) {
76             e.printStackTrace();
77             System.exit(-1);
78         }
79
80         /* Build the virtual dispatch tables */
81         buildVirtualTables(outvirtual);
82
83         /* Output includes */
84         outstructs.println("#include \"classdefs.h\"");
85         outmethodheader.println("#include \"structdefs.h\"");
86
87         /* Output types for short array and string */
88         outstructs.println("#define STRINGARRAYTYPE "+
89                            (state.getArrayNumber(
90                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
91
92         outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
93         outstructs.println("#define CHARARRAYTYPE "+
94                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
95         outstructs.println("#define NUMCLASSES "+state.numClasses());
96         if (state.TASK)
97             outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
98
99         // Output the C class declarations
100         // These could mutually reference each other
101         outclassdefs.println("struct "+arraytype+";");
102
103         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
104         while(it.hasNext()) {
105             ClassDescriptor cn=(ClassDescriptor)it.next();
106             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
107         }
108         outclassdefs.println("");
109         {
110             //Print out definition for array type
111             outclassdefs.println("struct "+arraytype+" {");
112             outclassdefs.println("  int type;");
113             if (state.TASK) {
114                 outclassdefs.println("  int flag;");
115                 outclassdefs.println("  void * flagptr;");
116             }
117             printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
118             outclassdefs.println("  int ___length___;");
119             outclassdefs.println("};\n");
120
121             if (state.TASK) {
122             //Print out definitions for task types
123                 outtask.println("struct parameterdescriptor {");
124                 outtask.println("int type;");
125                 outtask.println("int numberterms;");
126                 outtask.println("int *intarray;");
127                 outtask.println("void * queue;");
128                 outtask.println("};");
129
130                 outtask.println("struct taskdescriptor {");
131                 outtask.println("void * taskptr;");
132                 outtask.println("int numParameters;");
133                 outtask.println("struct parameterdescriptor **descriptorarray;");
134                 outtask.println("char * name;");
135                 outtask.println("};");
136                 outtask.println("extern struct taskdescriptor * taskarray[];");
137                 outtask.println("extern numtasks;");
138             }
139         }
140
141         // Output function prototypes and structures for parameters
142         it=state.getClassSymbolTable().getDescriptorsIterator();
143         while(it.hasNext()) {
144             ClassDescriptor cn=(ClassDescriptor)it.next();
145             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
146         }
147
148
149         if (state.TASK) {
150             /* Map flags to integers */
151             it=state.getClassSymbolTable().getDescriptorsIterator();
152             while(it.hasNext()) {
153                 ClassDescriptor cn=(ClassDescriptor)it.next();
154                 mapFlags(cn);
155             }
156             /* Generate Tasks */
157             generateTaskStructs(outstructs, outmethodheader);
158         }
159
160         outmethodheader.close();
161
162         /* Build the actual methods */
163         outmethod.println("#include \"methodheaders.h\"");
164         outmethod.println("#include \"virtualtable.h\"");
165         outmethod.println("#include <runtime.h>");
166         if (state.main!=null) {
167             outmethod.println("#include <string.h>");       
168         }
169
170         if (state.CONSCHECK) {
171             outmethod.println("#include \"checkers.h\"");
172         }
173         outclassdefs.println("extern int classsize[];");
174         outclassdefs.println("extern int hasflags[];");
175         outclassdefs.println("extern int * pointerarray[];");
176
177         //Store the sizes of classes & array elements
178         generateSizeArray(outmethod);
179         
180         //Store the layout of classes
181         generateLayoutStructs(outmethod);
182
183         /* Generate code for methods */
184         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
185         while(classit.hasNext()) {
186             ClassDescriptor cn=(ClassDescriptor)classit.next();
187             Iterator methodit=cn.getMethods();
188             while(methodit.hasNext()) {
189                 /* Classify parameters */
190                 MethodDescriptor md=(MethodDescriptor)methodit.next();
191                 FlatMethod fm=state.getMethodFlat(md);
192                 if (!md.getModifiers().isNative())
193                     generateFlatMethod(fm,outmethod);
194             }
195         }
196
197         if (state.TASK) {
198             /* Compile task based program */
199             outtaskdefs.println("#include \"task.h\"");
200             outtaskdefs.println("#include \"methodheaders.h\"");
201             Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
202             while(taskit.hasNext()) {
203                 TaskDescriptor td=(TaskDescriptor)taskit.next();
204                 FlatMethod fm=state.getMethodFlat(td);
205                 generateFlatMethod(fm, outmethod);
206                 generateTaskDescriptor(outtaskdefs, td);
207             }
208
209             {
210                 //Output task descriptors
211                 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
212                 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
213                 boolean first=true;
214                 while(taskit.hasNext()) {
215                     TaskDescriptor td=(TaskDescriptor)taskit.next();
216                     if (first)
217                         first=false;
218                     else
219                         outtaskdefs.println(",");
220                     outtaskdefs.print("&task_"+td.getSafeSymbol());
221                 }
222                 outtaskdefs.println("};");
223             }
224
225             outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
226
227         } else if (state.main!=null) {
228             /* Generate main method */
229             outmethod.println("int main(int argc, const char *argv[]) {");
230             outmethod.println("int i;");
231             outmethod.println("struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
232             outmethod.println("for(i=1;i<argc;i++) {");
233             outmethod.println("int length=strlen(argv[i]);");
234             outmethod.println("struct ___String___ *newstring=NewString(argv[i],length);");
235             outmethod.println("((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
236             outmethod.println("}");
237
238
239             ClassDescriptor cd=typeutil.getClass(state.main);
240             Set mainset=cd.getMethodTable().getSet("main");
241             for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
242                 MethodDescriptor md=(MethodDescriptor)mainit.next();
243                 if (md.numParameters()!=1)
244                     continue;
245                 if (md.getParameter(0).getType().getArrayCount()!=1)
246                     continue;
247                 if (!md.getParameter(0).getType().getSymbol().equals("String"))
248                     continue;
249
250                 if (!md.getModifiers().isStatic())
251                     throw new Error("Error: Non static main");
252                 outmethod.println("   "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
253                 break;
254             }
255             outmethod.println("}");
256         }
257         if (state.TASK)
258             outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
259
260
261         /* Output structure definitions for repair tool */
262         if (state.structfile!=null) {
263             buildRepairStructs(outrepairstructs);
264             outrepairstructs.close();
265         }
266
267         outstructs.close();
268         outmethod.close();
269     }
270
271     private int maxcount=0;
272
273     private void buildRepairStructs(PrintWriter outrepairstructs) {
274         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
275         while(classit.hasNext()) {
276             ClassDescriptor cn=(ClassDescriptor)classit.next();
277             outrepairstructs.println("structure "+cn.getSymbol()+" {");
278             outrepairstructs.println("  int __type__;");
279             if (state.TASK) {
280                 outrepairstructs.println("  int __flag__;");
281                 outrepairstructs.println("  int __flagptr__;");
282             }
283             printRepairStruct(cn, outrepairstructs);
284             outrepairstructs.println("}\n");
285         }
286         
287         for(int i=0;i<state.numArrays();i++) {
288             TypeDescriptor tdarray=arraytable[i];
289             TypeDescriptor tdelement=tdarray.dereference();
290             outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
291             outrepairstructs.println("  int __type__;");
292             printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
293             outrepairstructs.println("  int length;");
294             /*
295               // Need to add support to repair tool for this
296               if (tdelement.isClass()||tdelement.isArray())
297                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
298             else
299                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
300             */
301             outrepairstructs.println("}\n");
302         }
303
304     }
305
306     private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
307         ClassDescriptor sp=cn.getSuperDesc();
308         if (sp!=null)
309             printRepairStruct(sp, output);
310         
311         Vector fields=(Vector)fieldorder.get(cn);
312
313         for(int i=0;i<fields.size();i++) {
314             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
315             if (fd.getType().isArray()) {
316                 output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
317             } else if (fd.getType().isClass())
318                 output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
319             else 
320                 output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
321         }
322     }
323
324     /** This method outputs TaskDescriptor information */
325     void generateTaskDescriptor(PrintWriter output, TaskDescriptor task) {
326         for (int i=0;i<task.numParameters();i++) {
327             VarDescriptor param_var=task.getParameter(i);
328             TypeDescriptor param_type=task.getParamType(i);
329             FlagExpressionNode param_flag=task.getFlag(param_var);
330             DNFFlag dflag=param_flag.getDNF();
331             
332             Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
333                         
334             output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
335             for(int j=0;j<dflag.size();j++) {
336                 if (j!=0)
337                     output.println(",");
338                 Vector term=dflag.get(j);
339                 int andmask=0;
340                 int checkmask=0;
341                 for(int k=0;k<term.size();k++) {
342                     DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
343                     FlagDescriptor fd=dfa.getFlag();
344                     boolean negated=dfa.getNegated();
345                     int flagid=1<<((Integer)flags.get(fd)).intValue();
346                     andmask|=flagid;
347                     if (!negated)
348                         checkmask|=flagid;
349                 }
350                 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
351             }
352             output.println("};");
353
354             output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
355             output.println("/* type */"+param_type.getClassDesc().getId()+",");
356             output.println("/* number of DNF terms */"+dflag.size()+",");
357             output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
358             output.println("0");
359             output.println("};");
360         }
361
362
363         output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
364         for (int i=0;i<task.numParameters();i++) {
365             if (i!=0)
366                 output.println(",");
367             output.print("&parameter_"+i+"_"+task.getSafeSymbol());
368         }
369         output.println("};");
370
371         output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
372         output.println("&"+task.getSafeSymbol()+",");
373         output.println("/* number of parameters */" +task.numParameters() + ",");
374         output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
375         output.println("\""+task.getSymbol()+"\"");
376         output.println("};");
377     }
378
379
380     /** The buildVirtualTables method outputs the virtual dispatch
381      * tables for methods. */
382
383     private void buildVirtualTables(PrintWriter outvirtual) {
384         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
385         while(classit.hasNext()) {
386             ClassDescriptor cd=(ClassDescriptor)classit.next();
387             if (virtualcalls.getMethodCount(cd)>maxcount)
388                 maxcount=virtualcalls.getMethodCount(cd);
389         }
390         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
391
392         /* Fill in virtual table */
393         classit=state.getClassSymbolTable().getDescriptorsIterator();
394         while(classit.hasNext()) {
395             ClassDescriptor cd=(ClassDescriptor)classit.next();
396             fillinRow(cd, virtualtable, cd.getId());
397         }
398
399         ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
400         Iterator arrayit=state.getArrayIterator();
401         while(arrayit.hasNext()) {
402             TypeDescriptor td=(TypeDescriptor)arrayit.next();
403             int id=state.getArrayNumber(td);
404             fillinRow(objectcd, virtualtable, id+state.numClasses());
405         }
406         
407         outvirtual.print("void * virtualtable[]={");
408         boolean needcomma=false;
409         for(int i=0;i<state.numClasses()+state.numArrays();i++) {
410             for(int j=0;j<maxcount;j++) {
411                 if (needcomma)
412                     outvirtual.print(", ");
413                 if (virtualtable[i][j]!=null) {
414                     MethodDescriptor md=virtualtable[i][j];
415                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
416                 } else {
417                     outvirtual.print("0");
418                 }
419                 needcomma=true;
420             }
421             outvirtual.println("");
422         }
423         outvirtual.println("};");
424         outvirtual.close();
425     }
426
427     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
428         /* Get inherited methods */
429         if (cd.getSuperDesc()!=null)
430             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
431         /* Override them with our methods */
432         for(Iterator it=cd.getMethods();it.hasNext();) {
433             MethodDescriptor md=(MethodDescriptor)it.next();
434             if (md.isStatic()||md.getReturnType()==null)
435                 continue;
436             int methodnum=virtualcalls.getMethodNumber(md);
437             virtualtable[rownum][methodnum]=md;
438         }
439     }
440
441     /** Generate array that contains the sizes of class objects.  The
442      * object allocation functions in the runtime use this
443      * information. */
444
445     private void generateSizeArray(PrintWriter outclassdefs) {
446         outclassdefs.print("int classsize[]={");
447         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
448         cdarray=new ClassDescriptor[state.numClasses()];
449         while(it.hasNext()) {
450             ClassDescriptor cd=(ClassDescriptor)it.next();
451             cdarray[cd.getId()]=cd;
452         }
453         boolean needcomma=false;
454         for(int i=0;i<state.numClasses();i++) {
455             if (needcomma)
456                 outclassdefs.print(", ");
457             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
458             needcomma=true;
459         }
460
461         arraytable=new TypeDescriptor[state.numArrays()];
462
463         Iterator arrayit=state.getArrayIterator();
464         while(arrayit.hasNext()) {
465             TypeDescriptor td=(TypeDescriptor)arrayit.next();
466             int id=state.getArrayNumber(td);
467             arraytable[id]=td;
468         }
469         
470         for(int i=0;i<state.numArrays();i++) {
471             if (needcomma)
472                 outclassdefs.print(", ");
473             TypeDescriptor tdelement=arraytable[i].dereference();
474             if (tdelement.isArray()||tdelement.isClass())
475                 outclassdefs.print("sizeof(void *)");
476             else
477                 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
478             needcomma=true;
479         }
480
481         outclassdefs.println("};");
482     }
483
484     /** Constructs params and temp objects for each method or task.
485      * These objects tell the compiler which temps need to be
486      * allocated.  */
487
488     private void generateTempStructs(FlatMethod fm) {
489         MethodDescriptor md=fm.getMethod();
490         TaskDescriptor task=fm.getTask();
491
492         ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
493         if (md!=null)
494             paramstable.put(md, objectparams);
495         else
496             paramstable.put(task, objectparams);
497
498         for(int i=0;i<fm.numParameters();i++) {
499             TempDescriptor temp=fm.getParameter(i);
500             TypeDescriptor type=temp.getType();
501             if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
502                 objectparams.addPtr(temp);
503             else
504                 objectparams.addPrim(temp);
505         }
506
507         TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
508         if (md!=null)
509             tempstable.put(md, objecttemps);
510         else
511             tempstable.put(task, objecttemps);
512
513         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
514             FlatNode fn=(FlatNode)nodeit.next();
515             TempDescriptor[] writes=fn.writesTemps();
516             for(int i=0;i<writes.length;i++) {
517                 TempDescriptor temp=writes[i];
518                 TypeDescriptor type=temp.getType();
519                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
520                     objecttemps.addPtr(temp);
521                 else
522                     objecttemps.addPrim(temp);
523             }
524         }
525     }
526     
527     private void generateLayoutStructs(PrintWriter output) {
528         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
529         while(it.hasNext()) {
530             ClassDescriptor cn=(ClassDescriptor)it.next();
531             output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
532             Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
533             int count=0;
534             while(allit.hasNext()) {
535                 FieldDescriptor fd=(FieldDescriptor)allit.next();
536                 TypeDescriptor type=fd.getType();
537                 if (type.isPtr()||type.isArray())
538                     count++;
539             }
540             output.print(count);
541             allit=cn.getFieldTable().getAllDescriptorsIterator();
542             while(allit.hasNext()) {
543                 FieldDescriptor fd=(FieldDescriptor)allit.next();
544                 TypeDescriptor type=fd.getType();
545                 if (type.isPtr()||type.isArray()) {
546                     output.println(",");
547                     output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
548                 }
549             }
550             output.println("};");
551         }
552         output.println("int * pointerarray[]={");
553         boolean needcomma=false;
554         for(int i=0;i<state.numClasses();i++) {
555             ClassDescriptor cn=cdarray[i];
556             if (needcomma)
557                 output.println(",");
558             needcomma=true;
559             output.print(cn.getSafeSymbol()+"_pointers");
560         }
561
562         for(int i=0;i<state.numArrays();i++) {
563             if (needcomma)
564                 output.println(", ");
565             TypeDescriptor tdelement=arraytable[i].dereference();
566             if (tdelement.isArray()||tdelement.isClass())
567                 output.print("((int *)1)");
568             else
569                 output.print("0");
570             needcomma=true;
571         }
572         
573         output.println("};");
574         needcomma=false;
575         output.println("int hasflags[]={");
576         for(int i=0;i<state.numClasses();i++) {
577             ClassDescriptor cn=cdarray[i];
578             if (needcomma)
579                 output.println(", ");
580             needcomma=true;
581             if (cn.hasFlags())
582                 output.print("1");
583             else
584                 output.print("0");
585         }
586         output.println("};");
587     }
588
589     /* Force consistent field ordering between inherited classes. */
590
591     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
592         ClassDescriptor sp=cn.getSuperDesc();
593         if (sp!=null)
594             printClassStruct(sp, classdefout);
595         
596         if (!fieldorder.containsKey(cn)) {
597             Vector fields=new Vector();
598             fieldorder.put(cn,fields);
599             Iterator fieldit=cn.getFields();
600             while(fieldit.hasNext()) {
601                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
602                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
603                     fields.add(fd);
604             }
605         }
606         Vector fields=(Vector)fieldorder.get(cn);
607
608         for(int i=0;i<fields.size();i++) {
609             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
610             if (fd.getType().isClass()||fd.getType().isArray())
611                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
612             else 
613                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
614         }
615     }
616
617
618     /* Map flags to integers consistently between inherited
619      * classes. */
620
621     private void mapFlags(ClassDescriptor cn) {
622         ClassDescriptor sp=cn.getSuperDesc();
623         if (sp!=null)
624             mapFlags(sp);
625         int max=0;
626         if (!flagorder.containsKey(cn)) {
627             Hashtable flags=new Hashtable();
628             flagorder.put(cn,flags);
629             if (sp!=null) {
630                 Hashtable superflags=(Hashtable)flagorder.get(sp);
631                 Iterator superflagit=superflags.keySet().iterator();
632                 while(superflagit.hasNext()) {
633                     FlagDescriptor fd=(FlagDescriptor)superflagit.next();
634                     Integer number=(Integer)superflags.get(fd);
635                     flags.put(fd, number);
636                     if ((number.intValue()+1)>max)
637                         max=number.intValue()+1;
638                 }
639             }
640             
641             Iterator flagit=cn.getFlags();
642             while(flagit.hasNext()) {
643                 FlagDescriptor fd=(FlagDescriptor)flagit.next();
644                 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
645                     flags.put(fd, new Integer(max++));
646             }
647         }
648     }
649
650
651     /** This function outputs (1) structures that parameters are
652      * passed in (when PRECISE GC is enabled) and (2) function
653      * prototypes for the methods */
654
655     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
656         /* Output class structure */
657         classdefout.println("struct "+cn.getSafeSymbol()+" {");
658         classdefout.println("  int type;");
659         if (state.TASK) {
660             classdefout.println("  int flag;");
661             classdefout.println("  void * flagptr;");
662         }
663         printClassStruct(cn, classdefout);
664         classdefout.println("};\n");
665
666         /* Cycle through methods */
667         Iterator methodit=cn.getMethods();
668         while(methodit.hasNext()) {
669             /* Classify parameters */
670             MethodDescriptor md=(MethodDescriptor)methodit.next();
671             FlatMethod fm=state.getMethodFlat(md);
672             generateTempStructs(fm);
673
674             ParamsObject objectparams=(ParamsObject) paramstable.get(md);
675             TempObject objecttemps=(TempObject) tempstable.get(md);
676
677             /* Output parameter structure */
678             if (GENERATEPRECISEGC) {
679                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
680                 output.println("  int type;");
681                 output.println("  void * next;");
682                 for(int i=0;i<objectparams.numPointers();i++) {
683                     TempDescriptor temp=objectparams.getPointer(i);
684                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
685                 }
686                 output.println("};\n");
687             }
688
689             /* Output temp structure */
690             if (GENERATEPRECISEGC) {
691                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
692                 output.println("  int type;");
693                 output.println("  void * next;");
694                 for(int i=0;i<objecttemps.numPointers();i++) {
695                     TempDescriptor temp=objecttemps.getPointer(i);
696                     if (temp.getType().isNull())
697                         output.println("  void * "+temp.getSafeSymbol()+";");
698                     else
699                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
700                 }
701                 output.println("};\n");
702             }
703             
704             /* Output method declaration */
705             if (md.getReturnType()!=null) {
706                 if (md.getReturnType().isClass()||md.getReturnType().isArray())
707                     headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
708                 else
709                     headersout.print(md.getReturnType().getSafeSymbol()+" ");
710             } else 
711                 //catch the constructor case
712                 headersout.print("void ");
713             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
714             
715             boolean printcomma=false;
716             if (GENERATEPRECISEGC) {
717                 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
718                 printcomma=true;
719             }
720
721             //output parameter list
722             for(int i=0;i<objectparams.numPrimitives();i++) {
723                 TempDescriptor temp=objectparams.getPrimitive(i);
724                 if (printcomma)
725                     headersout.print(", ");
726                 printcomma=true;
727                 if (temp.getType().isClass()||temp.getType().isArray())
728                     headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
729                 else
730                     headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
731             }
732             headersout.println(");\n");
733         }
734     }
735
736
737     /** This function outputs (1) structures that parameters are
738      * passed in (when PRECISE GC is enabled) and (2) function
739      * prototypes for the tasks */
740
741     private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
742         /* Cycle through tasks */
743         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
744
745         while(taskit.hasNext()) {
746             /* Classify parameters */
747             TaskDescriptor task=(TaskDescriptor)taskit.next();
748             FlatMethod fm=state.getMethodFlat(task);
749             generateTempStructs(fm);
750
751             ParamsObject objectparams=(ParamsObject) paramstable.get(task);
752             TempObject objecttemps=(TempObject) tempstable.get(task);
753
754             /* Output parameter structure */
755             if (GENERATEPRECISEGC) {
756                 output.println("struct "+task.getSafeSymbol()+"_params {");
757
758                 output.println("  int type;");
759                 output.println("  void * next;");
760                 for(int i=0;i<objectparams.numPointers();i++) {
761                     TempDescriptor temp=objectparams.getPointer(i);
762                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
763                 }
764                 output.println("};\n");
765                 if (objectparams.numPointers()>maxtaskparams)
766                     maxtaskparams=objectparams.numPointers();
767             }
768
769             /* Output temp structure */
770             if (GENERATEPRECISEGC) {
771                 output.println("struct "+task.getSafeSymbol()+"_locals {");
772                 output.println("  int type;");
773                 output.println("  void * next;");
774                 for(int i=0;i<objecttemps.numPointers();i++) {
775                     TempDescriptor temp=objecttemps.getPointer(i);
776                     if (temp.getType().isNull())
777                         output.println("  void * "+temp.getSafeSymbol()+";");
778                     else
779                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
780                 }
781                 output.println("};\n");
782             }
783             
784             /* Output task declaration */
785             headersout.print("void " + task.getSafeSymbol()+"(");
786             
787             boolean printcomma=false;
788             if (GENERATEPRECISEGC) {
789                 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
790             } else
791                 headersout.print("void * parameterarray[]");
792             headersout.println(");\n");
793         }
794     }
795
796     /** Generate code for flatmethod fm. */
797
798     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
799         MethodDescriptor md=fm.getMethod();
800         TaskDescriptor task=fm.getTask();
801
802         ClassDescriptor cn=md!=null?md.getClassDesc():null;
803
804         ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
805
806         generateHeader(md!=null?md:task,output);
807
808         /* Print code */
809         
810         if (GENERATEPRECISEGC) {
811             if (md!=null)
812                 output.println("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+";");
813             else
814                 output.println("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+";");
815         }
816         TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
817         for(int i=0;i<objecttemp.numPrimitives();i++) {
818             TempDescriptor td=objecttemp.getPrimitive(i);
819             TypeDescriptor type=td.getType();
820             if (type.isNull())
821                 output.println("   void * "+td.getSafeSymbol()+";");
822             else if (type.isClass()||type.isArray())
823                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
824             else
825                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
826         }
827         
828
829         /* Generate labels first */
830         HashSet tovisit=new HashSet();
831         HashSet visited=new HashSet();
832         int labelindex=0;
833         Hashtable nodetolabel=new Hashtable();
834         tovisit.add(fm.methodEntryNode());
835         FlatNode current_node=null;
836
837         //Assign labels 1st
838         //Node needs a label if it is
839         while(!tovisit.isEmpty()) {
840             FlatNode fn=(FlatNode)tovisit.iterator().next();
841             tovisit.remove(fn);
842             visited.add(fn);
843             for(int i=0;i<fn.numNext();i++) {
844                 FlatNode nn=fn.getNext(i);
845                 if(i>0) {
846                     //1) Edge >1 of node
847                     nodetolabel.put(nn,new Integer(labelindex++));
848                 }
849                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
850                     tovisit.add(nn);
851                 } else {
852                     //2) Join point
853                     nodetolabel.put(nn,new Integer(labelindex++));
854                 }
855             }
856         }
857
858         //Do the actual code generation
859         tovisit=new HashSet();
860         visited=new HashSet();
861         tovisit.add(fm.methodEntryNode());
862         while(current_node!=null||!tovisit.isEmpty()) {
863             if (current_node==null) {
864                 current_node=(FlatNode)tovisit.iterator().next();
865                 tovisit.remove(current_node);
866             }
867             visited.add(current_node);
868             if (nodetolabel.containsKey(current_node))
869                 output.println("L"+nodetolabel.get(current_node)+":");
870             if (state.INSTRUCTIONFAILURE) {
871                 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
872             }
873             if (current_node.numNext()==0) {
874                 output.print("   ");
875                 generateFlatNode(fm, current_node, output);
876                 if (current_node.kind()!=FKind.FlatReturnNode) {
877                     output.println("   return;");
878                 }
879                 current_node=null;
880             } else if(current_node.numNext()==1) {
881                 output.print("   ");
882                 generateFlatNode(fm, current_node, output);
883                 FlatNode nextnode=current_node.getNext(0);
884                 if (visited.contains(nextnode)) {
885                     output.println("goto L"+nodetolabel.get(nextnode)+";");
886                     current_node=null;
887                 } else
888                     current_node=nextnode;
889             } else if (current_node.numNext()==2) {
890                 /* Branch */
891                 output.print("   ");
892                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
893                 if (!visited.contains(current_node.getNext(1)))
894                     tovisit.add(current_node.getNext(1));
895                 if (visited.contains(current_node.getNext(0))) {
896                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
897                     current_node=null;
898                 } else
899                     current_node=current_node.getNext(0);
900             } else throw new Error();
901         }
902
903
904         output.println("}\n\n");
905     }
906
907     /** Generate text string that corresponds to the Temp td. */
908     private String generateTemp(FlatMethod fm, TempDescriptor td) {
909         MethodDescriptor md=fm.getMethod();
910         TaskDescriptor task=fm.getTask();
911         TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
912         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
913             return td.getSafeSymbol();
914         }
915
916         if (objecttemps.isLocalPtr(td)) {
917             return localsprefix+"."+td.getSafeSymbol();
918         }
919
920         if (objecttemps.isParamPtr(td)) {
921             return paramsprefix+"->"+td.getSafeSymbol();
922         }
923         throw new Error();
924     }
925
926     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
927         switch(fn.kind()) {
928         case FKind.FlatCall:
929             generateFlatCall(fm, (FlatCall) fn,output);
930             return;
931         case FKind.FlatFieldNode:
932             generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
933             return;
934         case FKind.FlatElementNode:
935             generateFlatElementNode(fm, (FlatElementNode) fn,output);
936             return;
937         case FKind.FlatSetElementNode:
938             generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
939             return;
940         case FKind.FlatSetFieldNode:
941             generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
942             return;
943         case FKind.FlatNew:
944             generateFlatNew(fm, (FlatNew) fn,output);
945             return;
946         case FKind.FlatOpNode:
947             generateFlatOpNode(fm, (FlatOpNode) fn,output);
948             return;
949         case FKind.FlatCastNode:
950             generateFlatCastNode(fm, (FlatCastNode) fn,output);
951             return;
952         case FKind.FlatLiteralNode:
953             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
954             return;
955         case FKind.FlatReturnNode:
956             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
957             return;
958         case FKind.FlatNop:
959             output.println("/* nop */");
960             return;
961         case FKind.FlatCheckNode:
962             generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
963             return;
964         case FKind.FlatFlagActionNode:
965             generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
966             return;
967         }
968         throw new Error();
969
970     }
971
972     private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
973
974         if (state.CONSCHECK) {
975             String specname=fcn.getSpec();
976             String varname="repairstate___";
977             output.println("{");
978
979             output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
980
981
982             TempDescriptor[] temps=fcn.getTemps();
983             String[] vars=fcn.getVars();
984             for(int i=0;i<temps.length;i++) {
985                 output.println(varname+"->"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";");
986             }
987
988             output.println("if (doanalysis"+specname+"("+varname+")) {");
989             output.println("free"+specname+"_state("+varname+");");
990             output.println("} else {");
991             output.println("/* Bad invariant */");
992             output.println("free"+specname+"_state("+varname+");");
993             output.println("abort_task();");
994             output.println("}");
995
996             output.println("}");
997         }
998     }
999
1000     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1001         MethodDescriptor md=fc.getMethod();
1002         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1003         ClassDescriptor cn=md.getClassDesc();
1004         output.println("{");
1005         if (GENERATEPRECISEGC) {
1006             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1007             
1008             output.print(objectparams.getUID());
1009             output.print(", & "+localsprefix);
1010             if (fc.getThis()!=null) {
1011                 output.print(", ");
1012                 output.print(generateTemp(fm,fc.getThis()));
1013             }
1014             for(int i=0;i<fc.numArgs();i++) {
1015                 VarDescriptor var=md.getParameter(i);
1016                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1017                 if (objectparams.isParamPtr(paramtemp)) {
1018                     TempDescriptor targ=fc.getArg(i);
1019                     output.print(", ");
1020                     output.print(generateTemp(fm, targ));
1021                 }
1022             }
1023             output.println("};");
1024         }
1025         output.print("       ");
1026
1027
1028         if (fc.getReturnTemp()!=null)
1029             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1030         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1031             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1032         } else {
1033             
1034             output.print("((");
1035             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1036                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1037             else
1038                 output.print(md.getReturnType().getSafeSymbol()+" ");
1039             output.print("(*)(");
1040
1041             boolean printcomma=false;
1042             if (GENERATEPRECISEGC) {
1043                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1044                 printcomma=true;
1045             } 
1046
1047
1048             for(int i=0;i<objectparams.numPrimitives();i++) {
1049                 TempDescriptor temp=objectparams.getPrimitive(i);
1050                 if (printcomma)
1051                     output.print(", ");
1052                 printcomma=true;
1053                 if (temp.getType().isClass()||temp.getType().isArray())
1054                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1055                 else
1056                     output.print(temp.getType().getSafeSymbol());
1057             }
1058
1059             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1060         }
1061
1062         output.print("(");
1063         boolean needcomma=false;
1064         if (GENERATEPRECISEGC) {
1065             output.print("&__parameterlist__");
1066             needcomma=true;
1067         } else {
1068             if (fc.getThis()!=null) {
1069                 TypeDescriptor ptd=md.getThis().getType();
1070                 if (ptd.isClass()&&!ptd.isArray())
1071                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1072                 output.print(generateTemp(fm,fc.getThis()));
1073                 needcomma=true;
1074             }
1075         }
1076         for(int i=0;i<fc.numArgs();i++) {
1077             VarDescriptor var=md.getParameter(i);
1078             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1079             if (objectparams.isParamPrim(paramtemp)) {
1080                 TempDescriptor targ=fc.getArg(i);
1081                 if (needcomma)
1082                     output.print(", ");
1083
1084                 TypeDescriptor ptd=md.getParamType(i);
1085                 if (ptd.isClass()&&!ptd.isArray())
1086                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1087                 output.print(generateTemp(fm, targ));
1088                 needcomma=true;
1089             }
1090         }
1091         output.println(");");
1092         output.println("   }");
1093     }
1094
1095     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1096         Set subclasses=typeutil.getSubClasses(thiscd);
1097         if (subclasses==null)
1098             return true;
1099         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1100             ClassDescriptor cd=(ClassDescriptor)classit.next();
1101             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1102             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1103                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1104                 if (md.matches(matchmd))
1105                     return false;
1106             }
1107         }
1108         return true;
1109     }
1110
1111     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
1112         output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1113     }
1114
1115     private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
1116         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1117             throw new Error("Can't set array length");
1118         output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1119     }
1120
1121     private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1122         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1123         String type="";
1124
1125         if (elementtype.isArray()||elementtype.isClass())
1126             type="void *";
1127         else 
1128             type=elementtype.getSafeSymbol()+" ";
1129
1130         if (fen.needsBoundsCheck()) {
1131             output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1132             output.println("failedboundschk();");
1133         }
1134
1135         output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1136     }
1137
1138     private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1139         //TODO: need dynamic check to make sure this assignment is actually legal
1140         //Because Object[] could actually be something more specific...ie. Integer[]
1141
1142         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1143         String type="";
1144
1145         if (elementtype.isArray()||elementtype.isClass())
1146             type="void *";
1147         else 
1148             type=elementtype.getSafeSymbol()+" ";
1149
1150         if (fsen.needsBoundsCheck()) {
1151             output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1152             output.println("failedboundschk();");
1153         }
1154
1155         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1156     }
1157
1158     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1159         if (fn.getType().isArray()) {
1160             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1161             output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1162         } else
1163             output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1164     }
1165
1166     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1167
1168         if (fon.getRight()!=null)
1169             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1170         else if (fon.getOp().getOp()==Operation.ASSIGN)
1171             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1172         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1173             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1174         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1175             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1176         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1177             output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1178         else
1179             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1180     }
1181
1182     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1183         /* TODO: Do type check here */
1184         output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1185     }
1186
1187     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1188         if (fln.getValue()==null)
1189             output.println(generateTemp(fm, fln.getDst())+"=0;");
1190         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
1191             output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1192         else if (fln.getType().isBoolean()) {
1193             if (((Boolean)fln.getValue()).booleanValue())
1194                 output.println(generateTemp(fm, fln.getDst())+"=1;");
1195             else
1196                 output.println(generateTemp(fm, fln.getDst())+"=0;");
1197         } else if (fln.getType().isChar()) {
1198             String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1199             output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1200         } else
1201             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1202     }
1203
1204     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1205         
1206         if (frn.getReturnTemp()!=null)
1207             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1208         else
1209             output.println("return;");
1210     }
1211
1212     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1213         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1214     }
1215
1216     private void generateHeader(Descriptor des, PrintWriter output) {
1217         /* Print header */
1218         ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1219         MethodDescriptor md=null;
1220         TaskDescriptor task=null;
1221         if (des instanceof MethodDescriptor)
1222             md=(MethodDescriptor) des;
1223         else
1224             task=(TaskDescriptor) des;
1225
1226         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1227         
1228         if (md!=null&&md.getReturnType()!=null) {
1229             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1230                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1231             else
1232                 output.print(md.getReturnType().getSafeSymbol()+" ");
1233         } else 
1234             //catch the constructor case
1235             output.print("void ");
1236         if (md!=null)
1237             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1238         else
1239             output.print(task.getSafeSymbol()+"(");
1240         
1241         boolean printcomma=false;
1242         if (GENERATEPRECISEGC) {
1243             if (md!=null)
1244                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1245             else
1246                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1247             printcomma=true;
1248         } 
1249
1250         if (md!=null) {
1251             for(int i=0;i<objectparams.numPrimitives();i++) {
1252                 TempDescriptor temp=objectparams.getPrimitive(i);
1253                 if (printcomma)
1254                     output.print(", ");
1255                 printcomma=true;
1256                 if (temp.getType().isClass()||temp.getType().isArray())
1257                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1258                 else
1259                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1260             }
1261             output.println(") {");
1262         } else if (!GENERATEPRECISEGC) {
1263             output.println("void * parameterarray[]) {");
1264             for(int i=0;i<objectparams.numPrimitives();i++) {
1265                 TempDescriptor temp=objectparams.getPrimitive(i);
1266                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1267             }
1268             if (objectparams.numPrimitives()>maxtaskparams)
1269                 maxtaskparams=objectparams.numPrimitives();
1270         } else output.println(" {");
1271     }
1272
1273     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1274         output.println("/* FlatFlagActionNode */");
1275         Hashtable flagandtable=new Hashtable();
1276         Hashtable flagortable=new Hashtable();
1277
1278
1279         Iterator flagsit=ffan.getTempFlagPairs();
1280         while(flagsit.hasNext()) {
1281             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1282             TempDescriptor temp=tfp.getTemp();
1283             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1284             FlagDescriptor flag=tfp.getFlag();
1285             int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1286             boolean flagstatus=ffan.getFlagChange(tfp);
1287             if (flagstatus) {
1288                 int mask=0;
1289                 if (flagortable.containsKey(temp)) {
1290                     mask=((Integer)flagortable.get(temp)).intValue();
1291                 }
1292                 mask|=flagid;
1293                 flagortable.put(temp,new Integer(mask));
1294             } else {
1295                 int mask=0xFFFFFFFF;
1296                 if (flagandtable.containsKey(temp)) {
1297                     mask=((Integer)flagandtable.get(temp)).intValue();
1298                 }
1299                 mask&=(0xFFFFFFFF^flagid);
1300                 flagandtable.put(temp,new Integer(mask));
1301             }
1302         }
1303         Iterator orit=flagortable.keySet().iterator();
1304         while(orit.hasNext()) {
1305             TempDescriptor temp=(TempDescriptor)orit.next();
1306             int ormask=((Integer)flagortable.get(temp)).intValue();
1307             int andmask=0xFFFFFFF;
1308             if (flagandtable.containsKey(temp))
1309                 andmask=((Integer)flagandtable.get(temp)).intValue();
1310             output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1311         }
1312         Iterator andit=flagandtable.keySet().iterator();
1313         while(andit.hasNext()) {
1314             TempDescriptor temp=(TempDescriptor)andit.next();
1315             int andmask=((Integer)flagandtable.get(temp)).intValue();
1316             if (!flagortable.containsKey(temp))
1317                 output.println("flagorand("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");");
1318         }
1319     }
1320 }