cf269d1f22f764d3c6519d1a96e8504b09a1a880
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.*;
3 import java.util.*;
4 import java.io.*;
5
6 public class BuildCode {
7     State state;
8     Hashtable temptovar;
9     Hashtable paramstable;
10     Hashtable tempstable;
11     Hashtable fieldorder;
12     int tag=0;
13     String localsprefix="___locals___";
14     String paramsprefix="___params___";
15     public static boolean GENERATEPRECISEGC=false;
16     public static String PREFIX="";
17     Virtual virtualcalls;
18     TypeUtil typeutil;
19
20
21     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
22         state=st;
23         this.temptovar=temptovar;
24         paramstable=new Hashtable();    
25         tempstable=new Hashtable();
26         fieldorder=new Hashtable();
27         this.typeutil=typeutil;
28         virtualcalls=new Virtual(state);
29     }
30
31     public void buildCode() {
32         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
33         PrintWriter outclassdefs=null;
34         PrintWriter outstructs=null;
35         PrintWriter outmethodheader=null;
36         PrintWriter outmethod=null;
37         PrintWriter outvirtual=null;
38
39         try {
40             OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
41             outstructs=new java.io.PrintWriter(str, true);
42             str=new FileOutputStream(PREFIX+"methodheaders.h");
43             outmethodheader=new java.io.PrintWriter(str, true);
44             str=new FileOutputStream(PREFIX+"classdefs.h");
45             outclassdefs=new java.io.PrintWriter(str, true);
46             str=new FileOutputStream(PREFIX+"methods.c");
47             outmethod=new java.io.PrintWriter(str, true);
48             str=new FileOutputStream(PREFIX+"virtualtable.h");
49             outvirtual=new java.io.PrintWriter(str, true);
50         } catch (Exception e) {
51             e.printStackTrace();
52             System.exit(-1);
53         }
54
55         buildVirtualTables(outvirtual);
56         outstructs.println("#include \"classdefs.h\"");
57         outmethodheader.println("#include \"structdefs.h\"");
58
59         // Output the C declarations
60         // These could mutually reference each other
61         while(it.hasNext()) {
62             ClassDescriptor cn=(ClassDescriptor)it.next();
63             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
64         }
65         outclassdefs.println("");
66
67         it=state.getClassSymbolTable().getDescriptorsIterator();
68         while(it.hasNext()) {
69             ClassDescriptor cn=(ClassDescriptor)it.next();
70             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
71         }
72
73         outstructs.close();
74         outmethodheader.close();
75
76         /* Build the actual methods */
77         outmethod.println("#include \"methodheaders.h\"");
78         outmethod.println("#include \"virtualtable.h\"");
79         outmethod.println("#include <runtime.h>");
80
81         outclassdefs.println("extern int classsize[];");
82         generateSizeArray(outmethod);
83
84         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
85         while(classit.hasNext()) {
86             ClassDescriptor cn=(ClassDescriptor)classit.next();
87             Iterator methodit=cn.getMethods();
88             while(methodit.hasNext()) {
89                 /* Classify parameters */
90                 MethodDescriptor md=(MethodDescriptor)methodit.next();
91                 FlatMethod fm=state.getMethodFlat(md);
92                 if (!md.getModifiers().isNative())
93                     generateFlatMethod(fm,outmethod);
94             }
95         }
96         if (state.main!=null) {
97             outmethod.println("int main(int argc, const char *argv[]) {");
98             ClassDescriptor cd=typeutil.getClass(state.main);
99             Set mainset=cd.getMethodTable().getSet("main");
100             for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
101                 MethodDescriptor md=(MethodDescriptor)mainit.next();
102                 if (md.numParameters()!=0)
103                     continue;
104                 if (!md.getModifiers().isStatic())
105                     throw new Error("Error: Non static main");
106                 outmethod.println("   "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"();");
107                 break;
108             }
109             outmethod.println("}");
110         }
111         outmethod.close();
112     }
113
114     private int maxcount=0;
115
116     private void buildVirtualTables(PrintWriter outvirtual) {
117         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
118         while(classit.hasNext()) {
119             ClassDescriptor cd=(ClassDescriptor)classit.next();
120             if (virtualcalls.getMethodCount(cd)>maxcount)
121                 maxcount=virtualcalls.getMethodCount(cd);
122         }
123         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()][maxcount];
124
125         /* Fill in virtual table */
126         classit=state.getClassSymbolTable().getDescriptorsIterator();
127         while(classit.hasNext()) {
128             ClassDescriptor cd=(ClassDescriptor)classit.next();
129             fillinRow(cd, virtualtable, cd.getId());
130         }
131         outvirtual.print("void * virtualtable[]={");
132         boolean needcomma=false;
133         for(int i=0;i<state.numClasses();i++) {
134             for(int j=0;j<maxcount;j++) {
135                 if (needcomma)
136                     outvirtual.print(", ");
137                 if (virtualtable[i][j]!=null) {
138                     MethodDescriptor md=virtualtable[i][j];
139                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
140                 } else {
141                     outvirtual.print("0");
142                 }
143                 needcomma=true;
144             }
145             outvirtual.println("");
146         }
147         outvirtual.println("};");
148         outvirtual.close();
149     }
150
151     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
152         /* Get inherited methods */
153         if (cd.getSuperDesc()!=null)
154             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
155         /* Override them with our methods */
156         for(Iterator it=cd.getMethods();it.hasNext();) {
157             MethodDescriptor md=(MethodDescriptor)it.next();
158             if (md.isStatic()||md.getReturnType()==null)
159                 continue;
160             int methodnum=virtualcalls.getMethodNumber(md);
161             virtualtable[rownum][methodnum]=md;
162         }
163     }
164
165     private void generateSizeArray(PrintWriter outclassdefs) {
166         outclassdefs.print("int classsize[]={");
167         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
168         ClassDescriptor[] cdarray=new ClassDescriptor[state.numClasses()];
169         while(it.hasNext()) {
170             ClassDescriptor cd=(ClassDescriptor)it.next();
171             cdarray[cd.getId()]=cd;
172         }
173         boolean needcomma=false;
174         for(int i=0;i<state.numClasses();i++) {
175             if (needcomma)
176                 outclassdefs.print(", ");
177             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
178             needcomma=true;
179         }
180         outclassdefs.println("};");
181     }
182
183     private void generateTempStructs(FlatMethod fm) {
184         MethodDescriptor md=fm.getMethod();
185         ParamsObject objectparams=new ParamsObject(md,tag++);
186         paramstable.put(md, objectparams);
187         for(int i=0;i<fm.numParameters();i++) {
188             TempDescriptor temp=fm.getParameter(i);
189             TypeDescriptor type=temp.getType();
190             if (type.isPtr()&&GENERATEPRECISEGC)
191                 objectparams.addPtr(temp);
192             else
193                 objectparams.addPrim(temp);
194         }
195
196         TempObject objecttemps=new TempObject(objectparams,md,tag++);
197         tempstable.put(md, objecttemps);
198         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
199             FlatNode fn=(FlatNode)nodeit.next();
200             TempDescriptor[] writes=fn.writesTemps();
201             for(int i=0;i<writes.length;i++) {
202                 TempDescriptor temp=writes[i];
203                 TypeDescriptor type=temp.getType();
204                 if (type.isPtr()&&GENERATEPRECISEGC)
205                     objecttemps.addPtr(temp);
206                 else
207                     objecttemps.addPrim(temp);
208             }
209         }
210     }
211     
212     /* Force consistent field ordering between inherited classes */
213     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
214         ClassDescriptor sp=cn.getSuperDesc();
215         if (sp!=null)
216             printClassStruct(sp, classdefout);
217         
218         if (!fieldorder.containsKey(cn)) {
219             Vector fields=new Vector();
220             fieldorder.put(cn,fields);
221             Iterator fieldit=cn.getFields();
222             while(fieldit.hasNext()) {
223                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
224                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
225                     fields.add(fd);
226             }
227         }
228         Vector fields=(Vector)fieldorder.get(cn);
229
230         for(int i=0;i<fields.size();i++) {
231             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
232             if (fd.getType().isClass())
233                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
234             else 
235                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
236         }
237     }
238
239     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
240         /* Output class structure */
241         classdefout.println("struct "+cn.getSafeSymbol()+" {");
242         classdefout.println("  int type;");
243         printClassStruct(cn, classdefout);
244         classdefout.println("};\n");
245
246         /* Cycle through methods */
247         Iterator methodit=cn.getMethods();
248         while(methodit.hasNext()) {
249             /* Classify parameters */
250             MethodDescriptor md=(MethodDescriptor)methodit.next();
251             FlatMethod fm=state.getMethodFlat(md);
252             generateTempStructs(fm);
253
254             ParamsObject objectparams=(ParamsObject) paramstable.get(md);
255             TempObject objecttemps=(TempObject) tempstable.get(md);
256
257             /* Output parameter structure */
258             if (GENERATEPRECISEGC) {
259                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
260                 output.println("  int type;");
261                 output.println("  void * next;");
262                 for(int i=0;i<objectparams.numPointers();i++) {
263                     TempDescriptor temp=objectparams.getPointer(i);
264                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
265                 }
266                 output.println("};\n");
267             }
268
269             /* Output temp structure */
270             if (GENERATEPRECISEGC) {
271                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
272                 output.println("  int type;");
273                 output.println("  void * next;");
274                 for(int i=0;i<objecttemps.numPointers();i++) {
275                     TempDescriptor temp=objecttemps.getPointer(i);
276                     if (temp.getType().isNull())
277                         output.println("  void * "+temp.getSafeSymbol()+";");
278                     else
279                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
280                 }
281                 output.println("};\n");
282             }
283             
284             /* Output method declaration */
285             if (md.getReturnType()!=null) {
286                 if (md.getReturnType().isClass())
287                     headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
288                 else
289                     headersout.print(md.getReturnType().getSafeSymbol()+" ");
290             } else 
291                 //catch the constructor case
292                 headersout.print("void ");
293             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
294             
295             boolean printcomma=false;
296             if (GENERATEPRECISEGC) {
297                 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
298                 printcomma=true;
299             }
300
301             for(int i=0;i<objectparams.numPrimitives();i++) {
302                 TempDescriptor temp=objectparams.getPrimitive(i);
303                 if (printcomma)
304                     headersout.print(", ");
305                 printcomma=true;
306                 if (temp.getType().isClass())
307                     headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
308                 else
309                     headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
310             }
311             headersout.println(");\n");
312         }
313     }
314
315     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
316         MethodDescriptor md=fm.getMethod();
317         ClassDescriptor cn=md.getClassDesc();
318         ParamsObject objectparams=(ParamsObject)paramstable.get(md);
319
320         generateHeader(md,output);
321         /* Print code */
322         output.println(" {");
323         
324         if (GENERATEPRECISEGC) {
325             output.println("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+";");
326         }
327         TempObject objecttemp=(TempObject) tempstable.get(md);
328         for(int i=0;i<objecttemp.numPrimitives();i++) {
329             TempDescriptor td=objecttemp.getPrimitive(i);
330             TypeDescriptor type=td.getType();
331             if (type.isNull())
332                 output.println("   void * "+td.getSafeSymbol()+";");
333             else if (type.isClass())
334                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
335             else
336                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
337         }
338         
339
340         /* Generate labels first */
341         HashSet tovisit=new HashSet();
342         HashSet visited=new HashSet();
343         int labelindex=0;
344         Hashtable nodetolabel=new Hashtable();
345         tovisit.add(fm.methodEntryNode());
346         FlatNode current_node=null;
347
348         //Assign labels 1st
349         //Node needs a label if it is
350         while(!tovisit.isEmpty()) {
351             FlatNode fn=(FlatNode)tovisit.iterator().next();
352             tovisit.remove(fn);
353             visited.add(fn);
354             for(int i=0;i<fn.numNext();i++) {
355                 FlatNode nn=fn.getNext(i);
356                 if(i>0) {
357                     //1) Edge >1 of node
358                     nodetolabel.put(nn,new Integer(labelindex++));
359                 }
360                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
361                     tovisit.add(nn);
362                 } else {
363                     //2) Join point
364                     nodetolabel.put(nn,new Integer(labelindex++));
365                 }
366             }
367         }
368
369         //Do the actual code generation
370         tovisit=new HashSet();
371         visited=new HashSet();
372         tovisit.add(fm.methodEntryNode());
373         while(current_node!=null||!tovisit.isEmpty()) {
374             if (current_node==null) {
375                 current_node=(FlatNode)tovisit.iterator().next();
376                 tovisit.remove(current_node);
377             }
378             visited.add(current_node);
379             if (nodetolabel.containsKey(current_node))
380                 output.println("L"+nodetolabel.get(current_node)+":");
381             if (current_node.numNext()==0) {
382                 output.print("   ");
383                 generateFlatNode(fm, current_node, output);
384                 if (current_node.kind()!=FKind.FlatReturnNode) {
385                     output.println("   return;");
386                 }
387                 current_node=null;
388             } else if(current_node.numNext()==1) {
389                 output.print("   ");
390                 generateFlatNode(fm, current_node, output);
391                 FlatNode nextnode=current_node.getNext(0);
392                 if (visited.contains(nextnode)) {
393                     output.println("goto L"+nodetolabel.get(nextnode)+";");
394                     current_node=null;
395                 } else
396                     current_node=nextnode;
397             } else if (current_node.numNext()==2) {
398                 /* Branch */
399                 output.print("   ");
400                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
401                 if (!visited.contains(current_node.getNext(1)))
402                     tovisit.add(current_node.getNext(1));
403                 if (visited.contains(current_node.getNext(0))) {
404                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
405                     current_node=null;
406                 } else
407                     current_node=current_node.getNext(0);
408             } else throw new Error();
409         }
410         output.println("}\n\n");
411     }
412
413     private String generateTemp(FlatMethod fm, TempDescriptor td) {
414         MethodDescriptor md=fm.getMethod();
415         TempObject objecttemps=(TempObject) tempstable.get(md);
416         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
417             return td.getSafeSymbol();
418         }
419
420         if (objecttemps.isLocalPtr(td)) {
421             return localsprefix+"."+td.getSafeSymbol();
422         }
423
424         if (objecttemps.isParamPtr(td)) {
425             return paramsprefix+"->"+td.getSafeSymbol();
426         }
427         throw new Error();
428     }
429
430     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
431         switch(fn.kind()) {
432         case FKind.FlatCall:
433             generateFlatCall(fm, (FlatCall) fn,output);
434             return;
435         case FKind.FlatFieldNode:
436             generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
437             return;
438         case FKind.FlatSetFieldNode:
439             generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
440             return;
441         case FKind.FlatNew:
442             generateFlatNew(fm, (FlatNew) fn,output);
443             return;
444         case FKind.FlatOpNode:
445             generateFlatOpNode(fm, (FlatOpNode) fn,output);
446             return;
447         case FKind.FlatCastNode:
448             generateFlatCastNode(fm, (FlatCastNode) fn,output);
449             return;
450         case FKind.FlatLiteralNode:
451             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
452             return;
453         case FKind.FlatReturnNode:
454             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
455             return;
456         case FKind.FlatNop:
457             output.println("/* nop */");
458             return;
459         }
460         throw new Error();
461
462     }
463
464     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
465         MethodDescriptor md=fc.getMethod();
466         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
467         ClassDescriptor cn=md.getClassDesc();
468         output.println("{");
469         if (GENERATEPRECISEGC) {
470             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
471             
472             output.print(objectparams.getUID());
473             output.print(", & "+localsprefix);
474             if (fc.getThis()!=null) {
475                 output.print(", ");
476                 output.print(generateTemp(fm,fc.getThis()));
477             }
478             for(int i=0;i<fc.numArgs();i++) {
479                 VarDescriptor var=md.getParameter(i);
480                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
481                 if (objectparams.isParamPtr(paramtemp)) {
482                     TempDescriptor targ=fc.getArg(i);
483                     output.print(", ");
484                     output.print(generateTemp(fm, targ));
485                 }
486             }
487             output.println("};");
488         }
489         output.print("       ");
490
491
492         if (fc.getReturnTemp()!=null)
493             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
494         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
495             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
496         } else {
497             
498             output.print("((");
499             if (md.getReturnType().isClass())
500                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
501             else
502                 output.print(md.getReturnType().getSafeSymbol()+" ");
503             output.print("(*)(");
504
505             boolean printcomma=false;
506             if (GENERATEPRECISEGC) {
507                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
508                 printcomma=true;
509             } 
510
511
512             for(int i=0;i<objectparams.numPrimitives();i++) {
513                 TempDescriptor temp=objectparams.getPrimitive(i);
514                 if (printcomma)
515                     output.print(", ");
516                 printcomma=true;
517                 if (temp.getType().isClass())
518                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
519                 else
520                     output.print(temp.getType().getSafeSymbol());
521             }
522
523             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
524         }
525
526         output.print("(");
527         boolean needcomma=false;
528         if (GENERATEPRECISEGC) {
529             output.print("&__parameterlist__");
530             needcomma=true;
531         } else {
532             if (fc.getThis()!=null) {
533                 output.print(generateTemp(fm,fc.getThis()));
534                 needcomma=true;
535             }
536         }
537         for(int i=0;i<fc.numArgs();i++) {
538             VarDescriptor var=md.getParameter(i);
539             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
540             if (objectparams.isParamPrim(paramtemp)) {
541                 TempDescriptor targ=fc.getArg(i);
542                 if (needcomma)
543                     output.print(", ");
544                 output.print(generateTemp(fm, targ));
545                 needcomma=true;
546             }
547         }
548         output.println(");");
549         output.println("   }");
550     }
551
552     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
553         Set subclasses=typeutil.getSubClasses(thiscd);
554         if (subclasses==null)
555             return true;
556         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
557             ClassDescriptor cd=(ClassDescriptor)classit.next();
558             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
559             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
560                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
561                 if (md.matches(matchmd))
562                     return false;
563             }
564         }
565         return true;
566     }
567
568     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
569         output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
570     }
571
572     private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
573         output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
574     }
575
576     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
577         output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
578     }
579
580     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
581
582         if (fon.getRight()!=null)
583             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
584         else if (fon.getOp().getOp()==Operation.ASSIGN)
585             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
586         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
587             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
588         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
589             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
590         else if (fon.getOp().getOp()==Operation.POSTINC)
591             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"++;");
592         else if (fon.getOp().getOp()==Operation.POSTDEC)
593             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"--;");
594         else if (fon.getOp().getOp()==Operation.PREINC)
595             output.println(generateTemp(fm, fon.getDest())+" = ++"+generateTemp(fm, fon.getLeft())+";");
596         else if (fon.getOp().getOp()==Operation.PREDEC)
597             output.println(generateTemp(fm, fon.getDest())+" = --"+generateTemp(fm, fon.getLeft())+";");
598         else
599             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
600     }
601
602     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
603         /* TODO: Make call into runtime */
604         output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
605     }
606
607     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
608         if (fln.getValue()==null)
609             output.println(generateTemp(fm, fln.getDst())+"=0;");
610         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
611             output.println(generateTemp(fm, fln.getDst())+"=newstring(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\");");
612         else if (fln.getType().isBoolean()) {
613             if (((Boolean)fln.getValue()).booleanValue())
614                 output.println(generateTemp(fm, fln.getDst())+"=1;");
615             else
616                 output.println(generateTemp(fm, fln.getDst())+"=0;");
617         } else
618             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
619     }
620
621     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
622         if (frn.getReturnTemp()!=null)
623             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
624         else
625             output.println("return;");
626     }
627
628     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
629         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
630     }
631
632     private void generateHeader(MethodDescriptor md, PrintWriter output) {
633         /* Print header */
634         ParamsObject objectparams=(ParamsObject)paramstable.get(md);
635         ClassDescriptor cn=md.getClassDesc();
636         
637         if (md.getReturnType()!=null) {
638             if (md.getReturnType().isClass())
639                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
640             else
641                 output.print(md.getReturnType().getSafeSymbol()+" ");
642         } else 
643             //catch the constructor case
644             output.print("void ");
645
646         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
647         
648         boolean printcomma=false;
649         if (GENERATEPRECISEGC) {
650             output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
651             printcomma=true;
652         } 
653
654         for(int i=0;i<objectparams.numPrimitives();i++) {
655             TempDescriptor temp=objectparams.getPrimitive(i);
656             if (printcomma)
657                 output.print(", ");
658             printcomma=true;
659             if (temp.getType().isClass())
660                 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
661             else
662                 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
663         }
664         output.print(")");
665     }
666 }