methods=new SymbolTable();
classid=UIDCount++;
}
- private static int UIDCount=0;
+ private static int UIDCount=10; /* 0 is for Arrays */
+ /* For element types we use as defined in TypeDescriptor
+ public static final int BYTE=1;
+ public static final int SHORT=2;
+ public static final int INT=3;
+ public static final int LONG=4;
+ public static final int CHAR=5;
+ public static final int BOOLEAN=6;
+ public static final int FLOAT=7;
+ public static final int DOUBLE=8;*/
+
private final int classid;
String classname;
String superclass;
String paramsprefix="___params___";
public static boolean GENERATEPRECISEGC=false;
public static String PREFIX="";
+ public static String arraytype="___array___";
Virtual virtualcalls;
TypeUtil typeutil;
// Output the C declarations
// These could mutually reference each other
+ outclassdefs.println("struct "+arraytype+";");
while(it.hasNext()) {
ClassDescriptor cn=(ClassDescriptor)it.next();
outclassdefs.println("struct "+cn.getSafeSymbol()+";");
}
outclassdefs.println("");
-
+ {
+ //Print out definition for array type
+ outclassdefs.println("struct "+arraytype+" {");
+ outclassdefs.println(" int type;");
+ printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
+ outclassdefs.println(" int length;");
+ outclassdefs.println("};\n");
+ }
it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
ClassDescriptor cn=(ClassDescriptor)it.next();
if (virtualcalls.getMethodCount(cd)>maxcount)
maxcount=virtualcalls.getMethodCount(cd);
}
- MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()][maxcount];
+ MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
/* Fill in virtual table */
classit=state.getClassSymbolTable().getDescriptorsIterator();
ClassDescriptor cd=(ClassDescriptor)classit.next();
fillinRow(cd, virtualtable, cd.getId());
}
+
+ ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
+ Iteratory arrait=state.getArrayIterator();
+ while(arrayit.hasNext()) {
+ TypeDescriptor td=(TypeDescriptor)arrayit.next();
+ int id=getArrayNumber(td);
+ fillinRow(objectcd, virtualtable, id+state.numClasses());
+ }
+
outvirtual.print("void * virtualtable[]={");
boolean needcomma=false;
- for(int i=0;i<state.numClasses();i++) {
+ for(int i=0;i<state.numClasses()+state.numArrays();i++) {
for(int j=0;j<maxcount;j++) {
if (needcomma)
outvirtual.print(", ");
}
private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
- output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
+ if (fm.getType().isArray()) {
+ int arrayid=state.getArrayNumber(fm.getType())+state.numClasses();
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
+ } else
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
}
private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
return new NodePair(npe.getBegin(),fn);
}
+ private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
+ TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
+ TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
+ NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
+ NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
+ FlatElementNode fn=new FlatElementNode(tmp,tmpindex,out_temp);
+ npe.getEnd().addNext(npi.getBegin());
+ npi.getEnd().addNext(fn);
+ return new NodePair(npe.getBegin(),fn);
+ }
+
private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
// Two cases:
// left side is variable
FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
np_baseexp.getEnd().addNext(fsfn);
return new NodePair(np_src.getBegin(), fsfn);
+ } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
+ ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
+ ExpressionNode en=aan.getExpression();
+ ExpressionNode enindex=aan.getIndex();
+ TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
+ TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
+ NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+ NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
+ last.addNext(np_baseexp.getBegin());
+ np_baseexp.getEnd().addNext(np_indexexp.getBegin());
+ FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
+ np_indexexp.getEnd().addNext(fsen);
+ return new NodePair(np_src.getBegin(), fsen);
} else if (an.getDest().kind()==Kind.NameNode) {
NameNode nn=(NameNode)an.getDest();
if (nn.getExpression()!=null) {
return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
case Kind.FieldAccessNode:
return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
+ case Kind.ArrayAccessNode:
+ return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
case Kind.LiteralNode:
return flattenLiteralNode((LiteralNode)en,out_temp);
case Kind.MethodInvokeNode:
package IR.Flat;
public class FKind {
-
public static final int FlatCall=1;
public static final int FlatFieldNode=2;
public static final int FlatSetFieldNode=3;
public static final int FlatCondBranch=9;
public static final int FlatNop=10;
public static final int FlatSetElementNode=11;
+ public static final int FlatElementNode=12;
}
--- /dev/null
+package IR.Flat;
+import IR.FieldDescriptor;
+
+public class FlatElementNode extends FlatNode {
+ TempDescriptor src;
+ TempDescriptor dst;
+ TempDescriptor index;
+
+ public FlatElementNode(TempDescriptor src, TempDescriptor index, TempDescriptor dst) {
+ this.index=index;
+ this.src=src;
+ this.dst=dst;
+ }
+
+ public TempDescriptor getIndex() {
+ return index;
+ }
+
+ public TempDescriptor getSrc() {
+ return src;
+ }
+
+ public TempDescriptor getDst() {
+ return dst;
+ }
+
+ public String toString() {
+ return dst.toString()+"="+src.toString()+"["+index.toString()+"]";
+ }
+
+ public int kind() {
+ return FKind.FlatElementNode;
+ }
+
+ public TempDescriptor [] writesTemps() {
+ return new TempDescriptor[] {dst};
+ }
+
+ public TempDescriptor [] readsTemps() {
+ return new TempDescriptor[] {src,index};
+ }
+}
return dst;
}
+ public TempDescriptor getSize() {
+ return size;
+ }
+
public TypeDescriptor getType() {
return type;
}
this.treemethodmap=new Hashtable();
this.flatmethodmap=new Hashtable();
this.parsetrees=new HashSet();
+ this.arraytypes=new HashSet();
+ this.arraytonumber=new Hashtable();
}
public void addParseNode(ParseNode parsetree) {
public Set parsetrees;
public Hashtable treemethodmap;
public Hashtable flatmethodmap;
+ private HashSet arraytypes;
+ public Hashtable arraytonumber;
private int numclasses=0;
+ private int arraycount=0;
+ public void addArrayType(TypeDescriptor td) {
+ arraytypes.add(td);
+ arraytonumber.put(td,new Integer(arraycount++));
+ }
+
+ public Iterator getArrayIterator() {
+ return arraytypes.iterator();
+ }
+
+ public int getArrayNumber(TypeDescriptor td) {
+ return ((Integer)arraytonumber.get(td)).intValue();
+ }
+
+ public int numArrays() {
+ return arraytypes.size();
+ }
public static TypeDescriptor getTypeDescriptor(int t) {
TypeDescriptor td=new TypeDescriptor(t);
TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
Integer numdims=(Integer)nn.getChild("dims").getLiteral();
for(int i=0;i<numdims.intValue();i++)
- td=td.makeArray();
+ td=td.makeArray(state);
return td;
} else {
throw new Error();
ParseNode tmp=vardecl;
TypeDescriptor arrayt=t;
while (tmp.getChild("single")==null) {
- arrayt=arrayt.makeArray();
+ arrayt=arrayt.makeArray(state);
tmp=tmp.getChild("array");
}
String identifier=tmp.getChild("single").getTerminal();
if (pn.getChild("dims_opt").getLiteral()!=null)
num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
for(int i=0;i<args.size()+num;i++)
- td=td.makeArray();
+ td=td.makeArray(state);
CreateObjectNode con=new CreateObjectNode(td);
for(int i=0;i<args.size();i++) {
con.addArgument((ExpressionNode)args.get(i));
ParseNode tmp=vardecl;
TypeDescriptor arrayt=t;
while (tmp.getChild("single")==null) {
- arrayt=arrayt.makeArray();
+ arrayt=arrayt.makeArray(state);
tmp=tmp.getChild("array");
}
String identifier=tmp.getChild("single").getTerminal();
ParseNode tmp=paramn;
while (tmp.getChild("single")==null) {
- type=type.makeArray();
+ type=type.makeArray(state);
tmp=tmp.getChild("array");
}
String paramname=tmp.getChild("single").getTerminal();
return false;
if ((type==CLASS)&&(t.class_desc!=class_desc))
return false;
+ if (t.arraycount!=arraycount)
+ return false;
return true;
}
return false;
}
- public TypeDescriptor makeArray() {
+ public int hashCode() {
+ int hashcode=type^arraycount;
+ if (type==CLASS)
+ hashcode^=class_desc.hashCode();
+ return hashcode;
+ }
+
+ public TypeDescriptor makeArray(State state) {
TypeDescriptor td=new TypeDescriptor(getSymbol());
td.arraycount=arraycount+1;
td.type=type;
td.class_desc=class_desc;
+ state.addArrayType(td);
return td;
}