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