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