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