Hashtable paramstable;
Hashtable tempstable;
int tag=0;
+ String localsprefix="__locals__";
+ String paramsprefix="__params__";
private static final boolean GENERATEPRECISEGC=true;
public BuildCode(State st, Hashtable temptovar) {
PrintWriter outclassdefs=null;
PrintWriter outstructs=null;
PrintWriter outmethodheader=null;
+ PrintWriter outmethod=null;
try {
OutputStream str=new FileOutputStream("structdefs.h");
outstructs=new java.io.PrintWriter(str, true);
outmethodheader=new java.io.PrintWriter(str, true);
str=new FileOutputStream("classdefs.h");
outclassdefs=new java.io.PrintWriter(str, true);
+ str=new FileOutputStream("methods.c");
+ outmethod=new java.io.PrintWriter(str, true);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
outstructs.close();
outmethodheader.close();
+
+ /* Build the actual methods */
+ outmethod.println("#include \"methodheaders.h\"");
+ Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
+ while(classit.hasNext()) {
+ ClassDescriptor cn=(ClassDescriptor)classit.next();
+ generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
+ Iterator methodit=cn.getMethods();
+ while(methodit.hasNext()) {
+ /* Classify parameters */
+ MethodDescriptor md=(MethodDescriptor)methodit.next();
+ FlatMethod fm=state.getMethodFlat(md);
+ generateFlatMethod(fm,outmethod);
+ }
+ }
+ outmethod.close();
}
private void generateTempStructs(FlatMethod fm) {
/* Output parameter structure */
if (GENERATEPRECISEGC) {
- output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"params {");
+ output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
output.println(" int type;");
for(int i=0;i<objectparams.numPointers();i++) {
TempDescriptor temp=objectparams.getPointer(i);
/* Output temp structure */
if (GENERATEPRECISEGC) {
- output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"temps {");
+ output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps {");
output.println(" int type;");
for(int i=0;i<objecttemps.numPointers();i++) {
TempDescriptor temp=objecttemps.getPointer(i);
/* Output method declaration */
if (md.getReturnType()!=null)
headersout.print(md.getReturnType().getSafeSymbol()+" ");
- headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"(");
+ headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
boolean printcomma=false;
if (GENERATEPRECISEGC) {
- headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"params * base");
+ headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
printcomma=true;
}
for(int i=0;i<objectparams.numPrimitives();i++) {
private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
MethodDescriptor md=fm.getMethod();
+ ClassDescriptor cn=md.getClassDesc();
ParamsObject objectparams=(ParamsObject)paramstable.get(md);
generateHeader(md,output);
/* Print code */
+ output.println(" {");
- output.println("}");
+ if (GENERATEPRECISEGC) {
+ output.println(" struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps "+localsprefix+";");
+ }
+ TempObject objecttemp=(TempObject) tempstable.get(md);
+ for(int i=0;i<objecttemp.numPrimitives();i++) {
+ TempDescriptor td=objecttemp.getPrimitive(i);
+ TypeDescriptor type=td.getType();
+ if (type.isClass())
+ output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+ else
+ output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
+ }
+
+
+ /* Generate labels first */
+ HashSet tovisit=new HashSet();
+ HashSet visited=new HashSet();
+ int labelindex=0;
+ Hashtable nodetolabel=new Hashtable();
+ tovisit.add(fm.methodEntryNode());
+ FlatNode current_node=null;
+
+
+ //Assign labels 1st
+ //Node needs a label if it is
+ while(!tovisit.isEmpty()) {
+ FlatNode fn=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(fn);
+ visited.add(fn);
+ for(int i=0;i<fn.numNext();i++) {
+ FlatNode nn=fn.getNext(i);
+ if(i>0) {
+ //1) Edge >1 of node
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ if (!visited.contains(nn)) {
+ tovisit.add(nn);
+ } else {
+ //2) Join point
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ }
+ }
+
+ //Do the actual code generation
+ tovisit=new HashSet();
+ visited=new HashSet();
+ tovisit.add(fm.methodEntryNode());
+ while(current_node!=null||!tovisit.isEmpty()) {
+ if (current_node==null) {
+ current_node=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(current_node);
+ }
+ visited.add(current_node);
+ if (nodetolabel.containsKey(current_node))
+ output.println("L"+nodetolabel.get(current_node)+":");
+ if (current_node.numNext()==0) {
+ output.print(" ");
+ generateFlatNode(fm, current_node, output);
+ current_node=null;
+ } else if(current_node.numNext()==1) {
+ output.print(" ");
+ generateFlatNode(fm, current_node, output);
+ FlatNode nextnode=current_node.getNext(0);
+ if (visited.contains(nextnode)) {
+ output.println("goto L"+nodetolabel.get(nextnode));
+ current_node=null;
+ } else
+ current_node=nextnode;
+ } else if (current_node.numNext()==2) {
+ /* Branch */
+ output.print(" ");
+ generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ output.println("goto L"+nodetolabel.get(current_node.getNext(0)));
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
+ } else throw new Error();
+ }
+ output.println("}\n\n");
+ }
+
+ private String generateTemp(FlatMethod fm, TempDescriptor td) {
+ MethodDescriptor md=fm.getMethod();
+ TempObject objecttemps=(TempObject) tempstable.get(md);
+ if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
+ return td.getSafeSymbol();
+ }
+
+ if (objecttemps.isLocalPtr(td)) {
+ return localsprefix+"."+td.getSafeSymbol();
+ }
+
+ if (objecttemps.isParamPtr(td)) {
+ return paramsprefix+"->"+td.getSafeSymbol();
+ }
+ throw new Error();
+ }
+
+ private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
+ switch(fn.kind()) {
+ case FKind.FlatCall:
+ generateFlatCall(fm, (FlatCall) fn,output);
+ return;
+ case FKind.FlatFieldNode:
+ generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
+ return;
+ case FKind.FlatSetFieldNode:
+ generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
+ return;
+ case FKind.FlatNew:
+ generateFlatNew(fm, (FlatNew) fn,output);
+ return;
+ case FKind.FlatOpNode:
+ generateFlatOpNode(fm, (FlatOpNode) fn,output);
+ return;
+ case FKind.FlatCastNode:
+ generateFlatCastNode(fm, (FlatCastNode) fn,output);
+ return;
+ case FKind.FlatLiteralNode:
+ generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
+ return;
+ case FKind.FlatReturnNode:
+ generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
+ return;
+ case FKind.FlatNop:
+ output.println("/* nop */");
+ return;
+ }
+ throw new Error();
+
+ }
+
+ private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
+ MethodDescriptor md=fm.getMethod();
+ ClassDescriptor cn=md.getClassDesc();
+ output.println(" {");
+ boolean needcomma=false;
+ if (GENERATEPRECISEGC) {
+ output.print(" struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __paramlist__={");
+ if (fc.getThis()!=null) {
+ output.print(generateTemp(fm,fc.getThis()));
+ needcomma=true;
+ }
+ output.println("};");
+ }
+ output.print(" ");
+
+ /* TODO: Virtual dispatch */
+ if (fc.getReturnType()!=null)
+ output.print(generateTemp(fm,fc.getReturnType())+"=");
+ output.print(cn.getSafeSymbol()+md.getSafeSymbol()++"_"+md.getSafeMethodDescriptor()+"(");
+ needcomma=false;
+ if (GENERATEPRECISEGC) {
+ output.println("__parameterlist__");
+ needcomma=true;
+ }
+ output.println(");");
+ output.println(" }");
+ }
+
+ private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
+ output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
+ }
+
+ private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
+ output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
+ }
+
+ private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
+ }
+
+ private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
+ if (fon.getOp().getOp()==Operation.ASSIGN)
+ output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
+ else if (fon.getRight()!=null)
+ output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
+ else
+ output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
+ }
+
+ private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
+ /* TODO: Make call into runtime */
+ output.println(fcn.getDst()+"=("+fcn.getType().getSafeSymbol()+")"+fcn.getSrc()+";");
+ }
+
+ private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
+ }
+
+ private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
+ output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
+ }
+
+ private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
+ output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
}
private void generateHeader(MethodDescriptor md, PrintWriter output) {
if (md.getReturnType()!=null)
output.print(md.getReturnType().getSafeSymbol()+" ");
- output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"(");
+ output.print(cn.getSafeSymbol()+md.getSafeSymbol()++"_"+md.getSafeMethodDescriptor()+"(");
boolean printcomma=false;
if (GENERATEPRECISEGC) {
- output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"params * base");
+ output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
printcomma=true;
}
for(int i=0;i<objectparams.numPrimitives();i++) {
printcomma=true;
output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
}
- output.println(") {");
+ output.print(")");
}
}