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