methods=new SymbolTable();
classid=UIDCount++;
}
- 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 static int UIDCount=0;
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___";
+ public static String arraytype="ArrayObject";
Virtual virtualcalls;
TypeUtil typeutil;
outmethod.println("#include <runtime.h>");
outclassdefs.println("extern int classsize[];");
+ //Store the sizes of classes & array elements
generateSizeArray(outmethod);
Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
}
ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
- Iteratory arrait=state.getArrayIterator();
+ Iterator arrayit=state.getArrayIterator();
while(arrayit.hasNext()) {
TypeDescriptor td=(TypeDescriptor)arrayit.next();
- int id=getArrayNumber(td);
+ int id=state.getArrayNumber(td);
fillinRow(objectcd, virtualtable, id+state.numClasses());
}
outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
needcomma=true;
}
+
+ TypeDescriptor[] sizetable=new TypeDescriptor[state.numArrays()];
+
+ Iterator arrayit=state.getArrayIterator();
+ while(arrayit.hasNext()) {
+ TypeDescriptor td=(TypeDescriptor)arrayit.next();
+ int id=state.getArrayNumber(td);
+ sizetable[id]=td;
+ }
+
+ for(int i=0;i<state.numArrays();i++) {
+ if (needcomma)
+ outclassdefs.print(", ");
+ TypeDescriptor tdelement=sizetable[i].dereference();
+ if (tdelement.isArray()||tdelement.isClass())
+ outclassdefs.print("sizeof(void *)");
+ else
+ outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
+ needcomma=true;
+ }
+
outclassdefs.println("};");
}
for(int i=0;i<fields.size();i++) {
FieldDescriptor fd=(FieldDescriptor)fields.get(i);
- if (fd.getType().isClass())
+ if (fd.getType().isClass()||fd.getType().isArray())
classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
else
classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
/* Output method declaration */
if (md.getReturnType()!=null) {
- if (md.getReturnType().isClass())
+ if (md.getReturnType().isClass()||md.getReturnType().isArray())
headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
else
headersout.print(md.getReturnType().getSafeSymbol()+" ");
if (printcomma)
headersout.print(", ");
printcomma=true;
- if (temp.getType().isClass())
+ if (temp.getType().isClass()||temp.getType().isArray())
headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
else
headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
TypeDescriptor type=td.getType();
if (type.isNull())
output.println(" void * "+td.getSafeSymbol()+";");
- else if (type.isClass())
+ else if (type.isClass()||type.isArray())
output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
else
output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
case FKind.FlatFieldNode:
generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
return;
+ case FKind.FlatElementNode:
+ generateFlatElementNode(fm, (FlatElementNode) fn,output);
+ return;
+ case FKind.FlatSetElementNode:
+ generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
+ return;
case FKind.FlatSetFieldNode:
generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
return;
} else {
output.print("((");
- if (md.getReturnType().isClass())
+ if (md.getReturnType().isClass()||md.getReturnType().isArray())
output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
else
output.print(md.getReturnType().getSafeSymbol()+" ");
if (printcomma)
output.print(", ");
printcomma=true;
- if (temp.getType().isClass())
+ if (temp.getType().isClass()||temp.getType().isArray())
output.print("struct " + temp.getType().getSafeSymbol()+" * ");
else
output.print(temp.getType().getSafeSymbol());
output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
}
+ private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
+ TypeDescriptor elementtype=fen.getSrc().getType().dereference();
+ String type="";
+
+ if (elementtype.isArray()||elementtype.isClass())
+ type="void *";
+ else
+ type=elementtype.getSafeSymbol()+" ";
+ output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->length))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
+ }
+
+ private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
+ //TODO need dynamic check to make sure this assignment is actually legal
+ //Because Object[] could actually be something more specific...ie. Integer[]
+ TypeDescriptor elementtype=fsen.getDst().getType().dereference();
+ String type="";
+
+ if (elementtype.isArray()||elementtype.isClass())
+ type="void *";
+ else
+ type=elementtype.getSafeSymbol()+" ";
+
+ output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->length))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
+ }
+
private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
- if (fm.getType().isArray()) {
- int arrayid=state.getArrayNumber(fm.getType())+state.numClasses();
+ if (fn.getType().isArray()) {
+ int arrayid=state.getArrayNumber(fn.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()+");");
ClassDescriptor cn=md.getClassDesc();
if (md.getReturnType()!=null) {
- if (md.getReturnType().isClass())
+ if (md.getReturnType().isClass()||md.getReturnType().isArray())
output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
else
output.print(md.getReturnType().getSafeSymbol()+" ");
if (printcomma)
output.print(", ");
printcomma=true;
- if (temp.getType().isClass())
+ if (temp.getType().isClass()||temp.getType().isArray())
output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
else
output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
}
FlatNew fn=new FlatNew(td, out_temp, temps[0]);
last.addNext(fn);
- NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0);
- fn.addNext(np.getBegin());
- return new NodePair(first,np.getEnd());
+ if (temps.length>1) {
+ NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0);
+ fn.addNext(np.getBegin());
+ return new NodePair(first,np.getEnd());
+ } else
+ return new NodePair(first, fn);
}
}
fcb.addFalseNext(fnop);
fn.addNext(fsen);
//Recursive call here
- if ((i+1)<temparray.length) {
+ if ((i+2)<temparray.length) {
NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1);
fsen.addNext(np2.getBegin());
np2.getEnd().addNext(fon);
private int arraycount=0;
public void addArrayType(TypeDescriptor td) {
- arraytypes.add(td);
- arraytonumber.put(td,new Integer(arraycount++));
+ if (!arraytypes.contains(td)) {
+ arraytypes.add(td);
+ arraytonumber.put(td,new Integer(arraycount++));
+ }
}
public Iterator getArrayIterator() {
}
return con;
} else if (isNode(pn,"createarray")) {
+ System.out.println(pn.PPrint(3,true));
TypeDescriptor td=parseTypeDescriptor(pn);
Vector args=parseDimExprs(pn);
int num=0;
if (pn.getChild("dims_opt").getLiteral()!=null)
num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
- for(int i=0;i<args.size()+num;i++)
+ for(int i=0;i<(args.size()+num);i++)
td=td.makeArray(state);
CreateObjectNode con=new CreateObjectNode(td);
for(int i=0;i<args.size();i++) {
return new FieldAccessNode(en,fieldname);
} else if (isNode(pn,"arrayaccess")) {
ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
- ExpressionNode index=parseExpression(pn.getChild("index"));
+ ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
return new ArrayAccessNode(en,index);
} else if (isNode(pn,"cast1")) {
return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
}
public String printNode(int indent) {
- String st="new "+td.toString()+"(";
+ String st;
+ boolean isarray=td.isArray();
+ if (isarray)
+ st="new "+td.toString()+"[";
+ else
+ st="new "+td.toString()+"(";
for(int i=0;i<argumentlist.size();i++) {
ExpressionNode en=(ExpressionNode)argumentlist.get(i);
st+=en.printNode(indent);
- if ((i+1)!=argumentlist.size())
- st+=", ";
+ if ((i+1)!=argumentlist.size()) {
+ if (isarray)
+ st+="][";
+ else
+ st+=", ";
+ }
}
- return st+")";
+ if (isarray)
+ return st+"]";
+ else
+ return st+")";
}
public int kind() {
case Kind.FieldAccessNode:
checkFieldAccessNode(md,nametable,(FieldAccessNode)en,td);
return;
+ case Kind.ArrayAccessNode:
+ checkArrayAccessNode(md,nametable,(ArrayAccessNode)en,td);
+ return;
case Kind.LiteralNode:
checkLiteralNode(md,nametable,(LiteralNode)en,td);
return;
throw new Error("Field node returns "+fan.getType()+", but need "+td);
}
+ void checkArrayAccessNode(MethodDescriptor md, SymbolTable nametable, ArrayAccessNode aan, TypeDescriptor td) {
+ ExpressionNode left=aan.getExpression();
+ checkExpressionNode(md,nametable,left,null);
+
+ checkExpressionNode(md,nametable,aan.getIndex(),new TypeDescriptor(TypeDescriptor.INT));
+ TypeDescriptor ltd=left.getType();
+
+ if (td!=null)
+ if (!typeutil.isSuperorType(td,aan.getType()))
+ throw new Error("Field node returns "+aan.getType()+", but need "+td);
+ }
+
void checkLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode ln, TypeDescriptor td) {
/* Resolve the type */
Object o=ln.getValue();
checkExpressionNode(md, nametable, an.getSrc() ,td);
//TODO: Need check on validity of operation here
if (!((an.getDest() instanceof FieldAccessNode)||
+ (an.getDest() instanceof ArrayAccessNode)||
(an.getDest() instanceof NameNode)))
throw new Error("Bad lside in "+an.printNode(0));
checkExpressionNode(md, nametable, an.getDest(), null);
TypeDescriptor typetolookin=con.getType();
checkTypeDescriptor(typetolookin);
- if (!typetolookin.isClass())
- throw new Error();
-
- ClassDescriptor classtolookin=typetolookin.getClassDesc();
- System.out.println("Looking for "+typetolookin.getSymbol());
- System.out.println(classtolookin.getMethodTable());
-
- Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
- MethodDescriptor bestmd=null;
+ if ((!typetolookin.isClass())&&(!typetolookin.isArray()))
+ throw new Error("Can't allocate primitive type:"+con.printNode(0));
+
+ if (!typetolookin.isArray()) {
+ //Array's don't need constructor calls
+ ClassDescriptor classtolookin=typetolookin.getClassDesc();
+ System.out.println("Looking for "+typetolookin.getSymbol());
+ System.out.println(classtolookin.getMethodTable());
+
+ Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
+ MethodDescriptor bestmd=null;
NextMethod:
- for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
- MethodDescriptor currmd=(MethodDescriptor)methodit.next();
- /* Need correct number of parameters */
- System.out.println("Examining: "+currmd);
- if (con.numArgs()!=currmd.numParameters())
- continue;
- for(int i=0;i<con.numArgs();i++) {
- if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
- continue NextMethod;
- }
- /* Method okay so far */
- if (bestmd==null)
- bestmd=currmd;
- else {
- if (isMoreSpecific(currmd,bestmd)) {
+ for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
+ MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+ /* Need correct number of parameters */
+ System.out.println("Examining: "+currmd);
+ if (con.numArgs()!=currmd.numParameters())
+ continue;
+ for(int i=0;i<con.numArgs();i++) {
+ if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
+ continue NextMethod;
+ }
+ /* Method okay so far */
+ if (bestmd==null)
bestmd=currmd;
- } else if (!isMoreSpecific(bestmd, currmd))
- throw new Error("No method is most specific");
-
- /* Is this more specific than bestmd */
+ else {
+ if (isMoreSpecific(currmd,bestmd)) {
+ bestmd=currmd;
+ } else if (!isMoreSpecific(bestmd, currmd))
+ throw new Error("No method is most specific");
+
+ /* Is this more specific than bestmd */
+ }
}
+ if (bestmd==null)
+ throw new Error("No method found for "+con.printNode(0));
+ con.setConstructor(bestmd);
}
- if (bestmd==null)
- throw new Error("No method found for "+con.printNode(0));
- con.setConstructor(bestmd);
-
-
}
}
public boolean isArray() {
- return arraycount>0;
+ return (arraycount>0);
+ }
+
+ public int getArrayCount() {
+ return arraycount;
}
public TypeDescriptor dereference() {
}
public String getSafeSymbol() {
- if (isClass())
+ if (isArray())
+ return IR.Flat.BuildCode.arraytype;
+ else if (isClass())
return class_desc.getSafeSymbol();
else if (isByte())
return "char";
}
public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
+ //Matching type are always okay
+ if (possiblesuper.equals(cd2))
+ return true;
+
+ //Handle arrays
+ if (cd2.isArray()||possiblesuper.isArray()) {
+ // Object is super class of all arrays
+ if (possiblesuper.getSymbol().equals(ObjectClass)&&!possiblesuper.isArray())
+ return true;
+
+ // If we have the same dimensionality of arrays & both are classes, we can default to the normal test
+ if (cd2.isClass()&&possiblesuper.isClass()
+ &&(possiblesuper.getArrayCount()==cd2.getArrayCount())&&
+ isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc()))
+ return true;
+
+ // Object is superclass of all array classes
+ if (possiblesuper.getSymbol().equals(ObjectClass)&&cd2.isClass()
+ &&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
+ return true;
+
+ return false;
+ }
+
if (possiblesuper.isClass()&&
cd2.isClass())
return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
}
- public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+ private boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
if (possiblesuper==cd2)
return true;
else
return isSuper(possiblesuper, cd2);
}
- public boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+ private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
while(cd2!=null) {
cd2=getSuper(cd2);
if (cd2==possiblesuper)
// ;
dim_exprs ::= dim_expr:exp {:
ParseNode pn=new ParseNode("dim_exprs");
- pn.addChild("expr").addChild(exp);
- RESULT=exp; :}
+ pn.addChild(exp);
+ RESULT=pn; :}
| dim_exprs:base dim_expr:exp {:
base.addChild(exp);
RESULT=base;
*((int *)v)=type;
return v;
}
+
+void * allocate_newarray(int type, int length) {
+ void * v=calloc(1,sizeof(struct ArrayObject)+length*classsize[type]);
+ ((int *)v)[0]=type;
+ ((int *)v)[1]=length;
+ return v;
+}
void * allocate_new(int type);
+void * allocate_newarray(int type, int length);
#endif