import MCC.Compiler;
public class DotExpr extends Expr {
-
+
Expr left;
String field;
Expr index;
-
+
static boolean DOMEMCHECKS=false;
static boolean DOTYPECHECKS=false;
static boolean DONULL=false;
-
+
public DotExpr(Expr left, String field, Expr index) {
this.left = left;
this.field = field;
this.index = index;
}
+ public boolean isInvariant(Set vars) {
+ if (!left.isInvariant(vars))
+ return false;
+ if (intindex!=null)
+ return intindex.isInvariant(vars);
+ else
+ return true;
+ }
+
+ public Set findInvariants(Set vars) {
+ if (isInvariant(vars)) {
+ Set s=new HashSet();
+ s.add(this);
+ return s;
+ } else {
+ Set ls=left.findInvariants(vars);
+ if (intindex!=null) {
+ ls.addAll(intindex.findInvariants(vars));
+ Expr indexbound=((ArrayDescriptor)this.fd).getIndexBound();
+ ls.addAll(indexbound.findInvariants(vars));
+ if ((!(intindex instanceof IntegerLiteralExpr))||
+ ((IntegerLiteralExpr) intindex).getValue() != 0) {
+ FieldDescriptor fd=this.fd;
+ if (fd instanceof ArrayDescriptor)
+ fd=((ArrayDescriptor)fd).getField();
+ Expr basesize = fd.getBaseSizeExpr();
+ ls.addAll(basesize.findInvariants(vars));
+ }
+ }
+ return ls;
+ }
+ }
+
+
public boolean isSafe() {
if (!left.isSafe())
return false;
+
FieldDescriptor tmpfd=fd;
- if (tmpfd instanceof ArrayDescriptor)
- return false; // Arrays could be out of bounds
+
if (tmpfd.getPtr()) // Pointers cound be invalid
return false;
- return true;
- }
- public void findmatch(Descriptor d, Set s) {
- if (d==fd)
- s.add(this);
- left.findmatch(d,s);
- if (intindex!=null)
- intindex.findmatch(d,s);
+ if (tmpfd instanceof ArrayDescriptor) {
+ Expr arrayindex=((ArrayDescriptor)tmpfd).getIndexBound();
+ if (index instanceof IntegerLiteralExpr&&arrayindex instanceof IntegerLiteralExpr) {
+ int indexvalue=((IntegerLiteralExpr)index).getValue();
+ int arrayindexvalue=((IntegerLiteralExpr)arrayindex).getValue();
+ if (indexvalue>=0&&indexvalue<arrayindexvalue)
+ return true;
+ }
+ return false; // Otherwise, arrays could be out of bounds
+ }
+ return true;
}
public Set freeVars() {
name+="["+index.name()+"]";
return name;
}
-
+
+ public void findmatch(Descriptor d, Set s) {
+ if (d==fd)
+ s.add(this);
+ left.findmatch(d,s);
+ if (intindex!=null)
+ intindex.findmatch(d,s);
+ }
+
public Set useDescriptor(Descriptor d) {
HashSet newset=new HashSet();
if (d==fd)
public Set getRequiredDescriptors() {
Set v = left.getRequiredDescriptors();
-
+
if (intindex != null) {
v.addAll(intindex.getRequiredDescriptors());
}
+ v.add(fd);
return v;
}
public void generate(CodeWriter writer, VarDescriptor dest) {
VarDescriptor leftd = VarDescriptor.makeNew("left");
- writer.output("// " + leftd.getSafeSymbol() + " <-- ");
+ if (writer.getInvariantValue()!=null&&
+ writer.getInvariantValue().isInvariant(this)) {
+ writer.addDeclaration(getType().getGenerateType().getSafeSymbol().toString(), dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol()+"="+writer.getInvariantValue().getValue(this).getSafeSymbol()+";");
+ writer.outputline("maybe="+writer.getInvariantValue().getMaybe(this).getSafeSymbol()+";");
+ return;
+ }
+
+ writer.output("/* " + leftd.getSafeSymbol() + " <-- ");
left.prettyPrint(writer);
- writer.outputline("");
+ writer.outputline("*/");
left.generate(writer, leftd);
- writer.output("// " + leftd.getSafeSymbol() + " = ");
+ writer.output("/* " + leftd.getSafeSymbol() + " = ");
left.prettyPrint(writer);
- writer.outputline("");
-
+ writer.outputline("*/");
+
StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
Expr offsetbits;
// #ATTN#: getOffsetExpr needs to be called with the fielddescriptor object that is in the vector list
- // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array
+ // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array
// descriptor not the underlying field descriptor
/* we calculate the offset in bits */
-
+
offsetbits = struct.getOffsetExpr(fd);
FieldDescriptor fd=this.fd;
boolean doboundscheck=true;
boolean performedboundscheck=false;
- writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol()+"=0;");
+ writer.addDeclaration(getType().getGenerateType().toString(),dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol()+"=0;");
if (intindex != null) {
if (intindex instanceof IntegerLiteralExpr && ((IntegerLiteralExpr) intindex).getValue() == 0) {
indexvd.setType(ReservedTypeDescriptor.INT);
writer.getSymbolTable().add(indexvd);
- writer.output("// " + indexvd.getSafeSymbol() + " <-- ");
+ writer.output("/* " + indexvd.getSafeSymbol() + " <-- ");
intindex.prettyPrint(writer);
- writer.outputline("");
+ writer.outputline("*/");
intindex.generate(writer, indexvd);
- writer.output("// " + indexvd.getSafeSymbol() + " = ");
+ writer.output("/* " + indexvd.getSafeSymbol() + " = ");
intindex.prettyPrint(writer);
- writer.outputline("");
+ writer.outputline("*/");
Expr indexbound=((ArrayDescriptor)this.fd).getIndexBound();
VarDescriptor indexboundvd=VarDescriptor.makeNew("indexbound");
indexbound.generate(writer,indexboundvd);
-
+
writer.outputline("if ("+indexvd.getSafeSymbol()+">=0 &&"+indexvd.getSafeSymbol()+"<"+indexboundvd.getSafeSymbol()+")");
writer.startblock();
VarExpr indexve=new VarExpr(indexvd);
offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, indexve));
-
+
performedboundscheck=true;
} else
offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
public IRErrorReporter getErrorReporter() { throw new IRException("badness"); }
public SymbolTable getSymbolTable() { return st; }
});
-
+
if (td2 == null) {
throw new IRException();
} else if (td2 != ReservedTypeDescriptor.INT) {
throw new IRException();
}
-
+
boolean dotypecheck = false;
VarDescriptor ob = VarDescriptor.makeNew("offsetinbits");
- writer.output("// " + ob.getSafeSymbol() + " <-- ");
+ writer.output("/* " + ob.getSafeSymbol() + " <-- ");
offsetbits.prettyPrint(writer);
- writer.outputline("");
+ writer.outputline("*/");
offsetbits.generate(writer, ob);
- writer.output("// " + ob.getSafeSymbol() + " = ");
+ writer.output("/* " + ob.getSafeSymbol() + " = ");
offsetbits.prettyPrint(writer);
- writer.outputline("");
-
+ writer.outputline("*/");
+
/* derive offset in bytes */
VarDescriptor offset = VarDescriptor.makeNew("offset");
- writer.outputline("int " + offset.getSafeSymbol() + " = " + ob.getSafeSymbol() + " >> 3;");
-
+ writer.addDeclaration("int", offset.getSafeSymbol());
+ writer.outputline(offset.getSafeSymbol() + " = " + ob.getSafeSymbol() + " >> 3;");
+
if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
VarDescriptor shift = VarDescriptor.makeNew("shift");
- writer.outputline("int " + shift.getSafeSymbol() + " = " + ob.getSafeSymbol() +
+ writer.addDeclaration("int", shift.getSafeSymbol());
+ writer.outputline(shift.getSafeSymbol() + " = " + ob.getSafeSymbol() +
" - (" + offset.getSafeSymbol() + " << 3);");
int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
-
+
/* type var = ((*(int *) (base + offset)) >> shift) & mask */
writer.outputline("if ("+leftd.getSafeSymbol()+")");
- writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" +
- "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " +
- " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");
+ writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" +
+ "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " +
+ " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");
writer.outputline("else maybe=1;");
} else { /* a structure address or a ptr */
String ptr = fd.getPtr() ? "*(int *)" : "";
/* type var = [*(int *)] (base + offset) */
writer.outputline("if ("+leftd.getSafeSymbol()+")");
writer.startblock();
- writer.outputline(dest.getSafeSymbol() +
- " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
+ writer.outputline(dest.getSafeSymbol() +
+ " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
if (fd.getPtr()) {
writer.outputline("if ("+dest.getSafeSymbol()+")");
writer.startblock();
VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
- writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+ writer.addDeclaration("bool", typevar.getSafeSymbol());
+ writer.outputline(typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
dotypecheck = true;
} else if (DOTYPECHECKS) {
- writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+ writer.addDeclaration("bool", typevar.getSafeSymbol());
+ writer.outputline(typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
}
if (DOTYPECHECKS||DOMEMCHECKS) {
private int bitmask(int bits) {
int mask = 0;
-
+
for (int i = 0; i < bits; i++) {
mask <<= 1;
mask += 1;
}
- return mask;
+ return mask;
}
public void prettyPrint(PrettyPrinter pp) {
}
}
- public boolean isValue() {
+ public boolean isValue(TypeDescriptor td) {
FieldDescriptor tmpfd=fd;
if (tmpfd instanceof ArrayDescriptor)
tmpfd=((ArrayDescriptor)tmpfd).getField();
return (tmpfd.getPtr()||(tmpfd.getType() instanceof ReservedTypeDescriptor));
}
+ public boolean isPtr() {
+ FieldDescriptor tmpfd=fd;
+ if (tmpfd instanceof ArrayDescriptor)
+ tmpfd=((ArrayDescriptor)tmpfd).getField();
+ return tmpfd.getPtr();
+ }
+
boolean typechecked=false;
public TypeDescriptor typecheck(SemanticAnalyzer sa) {
if (typechecked)
else typechecked=true;
TypeDescriptor lefttype = left.typecheck(sa);
TypeDescriptor indextype = index == null ? null : index.typecheck(sa);
-
+
{
/* finished typechecking...so we can fill the fields in */
StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
assert intindex == null;
intindex = ld.getIndex();
} else {
+ if (fd==null) {
+ throw new Error("Null fd for: "+field);
+ }
fieldtype = fd.getType();
intindex=index;
}
this.fd=fd;
+ if (fieldtype instanceof MissingTypeDescriptor)
+ throw new Error(fieldtype.getSymbol()+" type undefined!");
}
if ((lefttype == null) || (index != null && indextype == null)) {
}
}
- if (lefttype instanceof StructureTypeDescriptor) {
+ if (lefttype instanceof StructureTypeDescriptor) {
StructureTypeDescriptor struct = (StructureTypeDescriptor) lefttype;
FieldDescriptor fd = struct.getField(field);
LabelDescriptor ld = struct.getLabel(field);
if (indextype == null && fd instanceof ArrayDescriptor) {
sa.getErrorReporter().report(null, "Must specify an index what accessing array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
- return null;
+ return null;
} else if (indextype != null && !(fd instanceof ArrayDescriptor)) {
sa.getErrorReporter().report(null, "Cannot specify an index when accessing non-array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
return null;
}
-
+
this.td = fd.getType();
} else if (ld != null) { /* label */
assert fd == null;
- if (index != null) {
+ if (index != null) {
sa.getErrorReporter().report(null, "A label cannot be accessed as an array");
return null;
}
-
+
this.td = ld.getType();
} else {
sa.getErrorReporter().report(null, "No such field or label '" + field + "' in structure '" + struct.getSymbol() + "'");
}
}
}
-