6 public class BuildCode {
12 String localsprefix="__locals__";
13 String paramsprefix="__params__";
14 private static final boolean GENERATEPRECISEGC=true;
16 public BuildCode(State st, Hashtable temptovar) {
18 this.temptovar=temptovar;
19 paramstable=new Hashtable();
20 tempstable=new Hashtable();
23 public void buildCode() {
24 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
25 PrintWriter outclassdefs=null;
26 PrintWriter outstructs=null;
27 PrintWriter outmethodheader=null;
28 PrintWriter outmethod=null;
30 OutputStream str=new FileOutputStream("structdefs.h");
31 outstructs=new java.io.PrintWriter(str, true);
32 str=new FileOutputStream("methodheaders.h");
33 outmethodheader=new java.io.PrintWriter(str, true);
34 str=new FileOutputStream("classdefs.h");
35 outclassdefs=new java.io.PrintWriter(str, true);
36 str=new FileOutputStream("methods.c");
37 outmethod=new java.io.PrintWriter(str, true);
38 } catch (Exception e) {
42 outstructs.println("#include \"classdefs.h\"");
43 outmethodheader.println("#include \"structdefs.h\"");
45 ClassDescriptor cn=(ClassDescriptor)it.next();
46 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
49 outmethodheader.close();
51 /* Build the actual methods */
52 outmethod.println("#include \"methodheaders.h\"");
53 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
54 while(classit.hasNext()) {
55 ClassDescriptor cn=(ClassDescriptor)classit.next();
56 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
57 Iterator methodit=cn.getMethods();
58 while(methodit.hasNext()) {
59 /* Classify parameters */
60 MethodDescriptor md=(MethodDescriptor)methodit.next();
61 FlatMethod fm=state.getMethodFlat(md);
62 generateFlatMethod(fm,outmethod);
68 private void generateTempStructs(FlatMethod fm) {
69 MethodDescriptor md=fm.getMethod();
70 ParamsObject objectparams=new ParamsObject(md,tag++);
71 paramstable.put(md, objectparams);
72 for(int i=0;i<fm.numParameters();i++) {
73 TempDescriptor temp=fm.getParameter(i);
74 TypeDescriptor type=temp.getType();
75 if (type.isPtr()&&GENERATEPRECISEGC)
76 objectparams.addPtr(temp);
78 objectparams.addPrim(temp);
81 TempObject objecttemps=new TempObject(objectparams,md,tag++);
82 tempstable.put(md, objecttemps);
83 for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
84 FlatNode fn=(FlatNode)nodeit.next();
85 TempDescriptor[] writes=fn.writesTemps();
86 for(int i=0;i<writes.length;i++) {
87 TempDescriptor temp=writes[i];
88 TypeDescriptor type=temp.getType();
89 if (type.isPtr()&&GENERATEPRECISEGC)
90 objecttemps.addPtr(temp);
92 objecttemps.addPrim(temp);
97 private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
98 /* Output class structure */
99 Iterator fieldit=cn.getFields();
100 classdefout.println("struct "+cn.getSafeSymbol()+" {");
101 classdefout.println(" int type;");
102 while(fieldit.hasNext()) {
103 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
104 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
106 classdefout.println("};\n");
108 /* Cycle through methods */
109 Iterator methodit=cn.getMethods();
110 while(methodit.hasNext()) {
111 /* Classify parameters */
112 MethodDescriptor md=(MethodDescriptor)methodit.next();
113 FlatMethod fm=state.getMethodFlat(md);
114 generateTempStructs(fm);
116 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
117 TempObject objecttemps=(TempObject) tempstable.get(md);
119 /* Output parameter structure */
120 if (GENERATEPRECISEGC) {
121 output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
122 output.println(" int type;");
123 for(int i=0;i<objectparams.numPointers();i++) {
124 TempDescriptor temp=objectparams.getPointer(i);
125 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSymbol()+";");
127 output.println(" void * next;");
128 output.println("};\n");
131 /* Output temp structure */
132 if (GENERATEPRECISEGC) {
133 output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps {");
134 output.println(" int type;");
135 for(int i=0;i<objecttemps.numPointers();i++) {
136 TempDescriptor temp=objecttemps.getPointer(i);
137 if (temp.getType().isNull())
138 output.println(" void * "+temp.getSymbol()+";");
140 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSymbol()+";");
142 output.println(" void * next;");
143 output.println("};\n");
146 /* Output method declaration */
147 if (md.getReturnType()!=null)
148 headersout.print(md.getReturnType().getSafeSymbol()+" ");
149 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
151 boolean printcomma=false;
152 if (GENERATEPRECISEGC) {
153 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
156 for(int i=0;i<objectparams.numPrimitives();i++) {
157 TempDescriptor temp=objectparams.getPrimitive(i);
159 headersout.print(", ");
161 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
163 headersout.println(");\n");
167 private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
168 MethodDescriptor md=fm.getMethod();
169 ClassDescriptor cn=md.getClassDesc();
170 ParamsObject objectparams=(ParamsObject)paramstable.get(md);
172 generateHeader(md,output);
174 output.println(" {");
176 if (GENERATEPRECISEGC) {
177 output.println(" struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps "+localsprefix+";");
179 TempObject objecttemp=(TempObject) tempstable.get(md);
180 for(int i=0;i<objecttemp.numPrimitives();i++) {
181 TempDescriptor td=objecttemp.getPrimitive(i);
182 TypeDescriptor type=td.getType();
184 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
186 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
190 /* Generate labels first */
191 HashSet tovisit=new HashSet();
192 HashSet visited=new HashSet();
194 Hashtable nodetolabel=new Hashtable();
195 tovisit.add(fm.methodEntryNode());
196 FlatNode current_node=null;
199 //Node needs a label if it is
200 while(!tovisit.isEmpty()) {
201 FlatNode fn=(FlatNode)tovisit.iterator().next();
204 for(int i=0;i<fn.numNext();i++) {
205 FlatNode nn=fn.getNext(i);
208 nodetolabel.put(nn,new Integer(labelindex++));
210 if (!visited.contains(nn)) {
214 nodetolabel.put(nn,new Integer(labelindex++));
219 //Do the actual code generation
220 tovisit=new HashSet();
221 visited=new HashSet();
222 tovisit.add(fm.methodEntryNode());
223 while(current_node!=null||!tovisit.isEmpty()) {
224 if (current_node==null) {
225 current_node=(FlatNode)tovisit.iterator().next();
226 tovisit.remove(current_node);
228 visited.add(current_node);
229 if (nodetolabel.containsKey(current_node))
230 output.println("L"+nodetolabel.get(current_node)+":");
231 if (current_node.numNext()==0) {
233 generateFlatNode(fm, current_node, output);
235 } else if(current_node.numNext()==1) {
237 generateFlatNode(fm, current_node, output);
238 FlatNode nextnode=current_node.getNext(0);
239 if (visited.contains(nextnode)) {
240 output.println("goto L"+nodetolabel.get(nextnode));
243 current_node=nextnode;
244 } else if (current_node.numNext()==2) {
247 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
248 if (!visited.contains(current_node.getNext(1)))
249 tovisit.add(current_node.getNext(1));
250 if (visited.contains(current_node.getNext(0))) {
251 output.println("goto L"+nodetolabel.get(current_node.getNext(0)));
254 current_node=current_node.getNext(0);
255 } else throw new Error();
257 output.println("}\n\n");
260 private String generateTemp(FlatMethod fm, TempDescriptor td) {
261 MethodDescriptor md=fm.getMethod();
262 TempObject objecttemps=(TempObject) tempstable.get(md);
263 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
264 return td.getSafeSymbol();
267 if (objecttemps.isLocalPtr(td)) {
268 return localsprefix+"."+td.getSafeSymbol();
271 if (objecttemps.isParamPtr(td)) {
272 return paramsprefix+"->"+td.getSafeSymbol();
277 private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
280 generateFlatCall(fm, (FlatCall) fn,output);
282 case FKind.FlatFieldNode:
283 generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
285 case FKind.FlatSetFieldNode:
286 generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
289 generateFlatNew(fm, (FlatNew) fn,output);
291 case FKind.FlatOpNode:
292 generateFlatOpNode(fm, (FlatOpNode) fn,output);
294 case FKind.FlatCastNode:
295 generateFlatCastNode(fm, (FlatCastNode) fn,output);
297 case FKind.FlatLiteralNode:
298 generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
300 case FKind.FlatReturnNode:
301 generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
304 output.println("/* nop */");
311 private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
312 MethodDescriptor md=fm.getMethod();
313 ClassDescriptor cn=md.getClassDesc();
315 boolean needcomma=false;
316 if (GENERATEPRECISEGC) {
317 output.print(" struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __paramlist__={");
318 if (fc.getThis()!=null) {
319 output.print(generateTemp(fm,fc.getThis()));
322 output.println("};");
326 /* TODO: Virtual dispatch */
327 if (fc.getReturnTemp()!=null)
328 output.print(generateTemp(fm,fc.getReturnTemp())+"=");
329 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
331 if (GENERATEPRECISEGC) {
332 output.println("__parameterlist__");
335 output.println(");");
336 output.println(" }");
339 private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
340 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
343 private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
344 output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
347 private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
348 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
351 private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
353 if (fon.getRight()!=null)
354 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
355 else if (fon.getOp().getOp()==Operation.ASSIGN)
356 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
357 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
358 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
359 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
360 output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
361 else if (fon.getOp().getOp()==Operation.POSTINC)
362 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"++;");
363 else if (fon.getOp().getOp()==Operation.POSTDEC)
364 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"--;");
365 else if (fon.getOp().getOp()==Operation.PREINC)
366 output.println(generateTemp(fm, fon.getDest())+" = ++"+generateTemp(fm, fon.getLeft())+";");
367 else if (fon.getOp().getOp()==Operation.PREDEC)
368 output.println(generateTemp(fm, fon.getDest())+" = --"+generateTemp(fm, fon.getLeft())+";");
370 output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
373 private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
374 /* TODO: Make call into runtime */
375 output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
378 private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
379 if (fln.getValue()==null)
380 output.println(generateTemp(fm, fln.getDst())+"=0;");
381 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
382 output.println(generateTemp(fm, fln.getDst())+"=newstring(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\");");
384 output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
387 private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
388 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
391 private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
392 output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
395 private void generateHeader(MethodDescriptor md, PrintWriter output) {
397 ParamsObject objectparams=(ParamsObject)paramstable.get(md);
398 ClassDescriptor cn=md.getClassDesc();
400 if (md.getReturnType()!=null)
401 output.print(md.getReturnType().getSafeSymbol()+" ");
402 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
404 boolean printcomma=false;
405 if (GENERATEPRECISEGC) {
406 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
409 for(int i=0;i<objectparams.numPrimitives();i++) {
410 TempDescriptor temp=objectparams.getPrimitive(i);
414 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());