Expr left;
String field;
Expr index;
+
+ static boolean DOMEMCHECKS=true;
+ static boolean DOTYPECHECKS=false;
+ static boolean DONULL=false;
+
+ public void findmatch(Descriptor d, Set s) {
+ if (d==fd)
+ s.add(this);
+ left.findmatch(d,s);
+ if (index!=null)
+ index.findmatch(d,s);
+ }
+
+ public Set freeVars() {
+ Set lset=left.freeVars();
+ Set iset=null;
+ if (index!=null)
+ iset=index.freeVars();
+ if (lset==null)
+ return iset;
+ if (iset!=null)
+ lset.addAll(iset);
+ return lset;
+ }
/*
static int memoryindents = 0;
left.prettyPrint(writer);
writer.outputline("");
- StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
+ StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
Expr intindex = index;
Expr offsetbits;
- // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor obect that is in teh vector list
+ // #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
// descriptor not the underlying field descriptor
/* we calculate the offset in bits */
- offsetbits = struct.getOffsetExpr(fd);
-
- if (fd instanceof ArrayDescriptor) {
- fd = ((ArrayDescriptor) fd).getField();
- }
+ offsetbits = struct.getOffsetExpr(fd);
+
+ FieldDescriptor fd=this.fd;
+ if (fd instanceof ArrayDescriptor)
+ fd=((ArrayDescriptor)fd).getField();
+
if (intindex != null) {
if (intindex instanceof IntegerLiteralExpr && ((IntegerLiteralExpr) intindex).getValue() == 0) {
- /* short circuit for constant 0 */
+ /* short circuit for constant 0 */
} else {
Expr basesize = fd.getBaseSizeExpr();
offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
}
}
-
- final SymbolTable st = writer.getSymbolTable();
- TypeDescriptor td = offsetbits.typecheck(new SemanticAnalyzer() {
- public IRErrorReporter getErrorReporter() { throw new IRException("badness"); }
- public SymbolTable getSymbolTable() { return st; }
- });
-
- if (td == null) {
- throw new IRException();
- } else if (td != ReservedTypeDescriptor.INT) {
- throw new IRException();
- }
-
- // #TBD#: ptr's to bits and byte's and stuff are a little iffy...
- // right now, a bit* is the same as a int* = short* = byte* (that is there
- // is no post-derefernce mask)
-
- // #ATTN#: do we handle int* correctly? what is the correct behavior? we automatically
- // dereference pointers, but for structures that means that if we have a nested structure
- // we return an integer address to that nested structure. if we have a pointer to a
- // structure else where we want that base address ... yeah so we *(int *) it... ok we are
- // correct
+ final SymbolTable st = writer.getSymbolTable();
+ TypeDescriptor td2 = offsetbits.typecheck(new SemanticAnalyzer() {
+ 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;
if (offsetbits instanceof IntegerLiteralExpr) {
int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
/* type var = ((*(int *) (base + offset)) >> shift) & mask */
- writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() +
- " = ((*(int *)" +
+ writer.outputline(getType().getGenerateType() + " "+dest.getSafeSymbol()+"=0;");
+ writer.outputline("if ("+leftd.getSafeSymbol()+")");
+ writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" +
"(" + leftd.getSafeSymbol() + " + " + offset + ")) " +
- " >> " + shift + ") & 0x" + Integer.toHexString(mask) + ";");
+ " >> " + shift + ") & 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) */
-
- // #ATTN: was 'getType.getGeneratedType()' instead of 'int' but all pointers are represented
- // by integers
- writer.outputline("int " + dest.getSafeSymbol() +
+ writer.outputline("int " + dest.getSafeSymbol()+"=0;");
+ writer.outputline("if ("+leftd.getSafeSymbol()+")");
+ writer.startblock();
+ writer.outputline(dest.getSafeSymbol() +
" = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ");");
-
- dotypecheck = true;
+ 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() + ");");
+ dotypecheck = true;
+ } else if (DOTYPECHECKS) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+ }
+ writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+ writer.startblock();
+ writer.outputline(dest.getSafeSymbol()+"=0;");
+ if (DONULL)
+ writer.outputline(ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ")=0;");
+ writer.endblock();
+ writer.endblock();
+ }
+ writer.endblock();
+ writer.outputline("else maybe=1;");
}
} else { /* offset in bits is an expression that must be generated */
VarDescriptor ob = VarDescriptor.makeNew("offsetinbits");
int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
/* type var = ((*(int *) (base + offset)) >> shift) & mask */
- writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() +
+ writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol()+"=0;");
+ writer.outputline("if ("+leftd.getSafeSymbol()+")");
+ 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) */
-
- // #ATTN: was 'getType.getGeneratedType()' instead of 'int' but all pointers are represented
- // by integers
- writer.outputline("int " + dest.getSafeSymbol() +
+ writer.outputline("int " + dest.getSafeSymbol() +"=0;");
+ writer.outputline("if ("+leftd.getSafeSymbol()+")");
+ writer.startblock();
+ writer.outputline(dest.getSafeSymbol() +
" = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
- dotypecheck = true;
- }
- }
-
-
- if (dotypecheck) { /* typemap checks! */
- // dest is 'low'
- // high is 'low' + sizeof(fd.getDataStructure) <<< can be cached!!
-
- // #ATTN#: we need to get the size of the fieldtype (if its a label the type of the label, not the
- // underlying field's type
-
- Expr sizeofexpr = fieldtype.getSizeExpr();
- VarDescriptor sizeof = VarDescriptor.makeNew("sizeof");
- sizeofexpr.generate(writer, sizeof);
-
- String low = dest.getSafeSymbol();
- String high = VarDescriptor.makeNew("high").getSafeSymbol();
- writer.outputline("int " + high + " = " + low + " + " + sizeof.getSafeSymbol() + ";");
- writer.outputline("assertvalidmemory(" + low + ", " + high + ");");
-
- // we need to null value check and conditionalize the rest of the rule... we'll use a hack
- // here where we store the number of indents in this class... and then provide a static
- // method to unwind...
- //writer.outputline("// assertvalidmemory ");
- //DotExpr.memoryindents++;
- //writer.outputline("if (" + dest.getSafeSymbol() + " != NULL)");
- //writer.startblock();
+ 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() + ");");
+ dotypecheck = true;
+ } else if (DOTYPECHECKS) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+ }
+ writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+ writer.startblock();
+ writer.outputline(dest.getSafeSymbol()+"=0;");
+ if (DONULL)
+ writer.outputline(ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")=0;");
+ writer.endblock();
+ writer.endblock();
+ }
+ writer.endblock();
+ writer.outputline("else maybe=1;");
+ }
}
-
}
private int bitmask(int bits) {
}
}
+ boolean typechecked=false;
public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+ if (typechecked)
+ return this.td;
+ else typechecked=true;
TypeDescriptor lefttype = left.typecheck(sa);
TypeDescriptor indextype = index == null ? null : index.typecheck(sa);
sa.getErrorReporter().report(null, "Left hand side of . expression must be a structure type, not '" + lefttype.getSymbol() + "'");
return null;
}
-
-
}
-
}