Expr left;
String field;
Expr index;
+
+ static boolean DOMEMCHECKS=true;
+ static boolean DOTYPECHECKS=false;
+ static boolean DONULL=false;
public Set freeVars() {
Set lset=left.freeVars();
left.prettyPrint(writer);
writer.outputline("");
- StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
+ StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
Expr intindex = index;
Expr offsetbits;
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
-
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.outputline(dest.getSafeSymbol() +
" = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ");");
-
- dotypecheck = true;
+ writer.outputline("else maybe=1;");
+ if (fd.getPtr()) {
+ VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+ if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+ dotypecheck = true;
+ } else if (DOTYPECHECKS) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + 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();
+ }
}
} 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.outputline(dest.getSafeSymbol() +
" = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
- dotypecheck = true;
+ writer.outputline("else maybe=1;");
+ if (fd.getPtr()) {
+ VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+ if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+ dotypecheck = true;
+ } else if (DOTYPECHECKS) {
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + 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();
+ }
}
}
-
-
- 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();
- }
-
}
private int bitmask(int bits) {
left.generate(writer, leftd);
writer.outputline("// 3-valued NOT");
- writer.outputline("if (!maybe)");
+ // writer.outputline("if (!maybe)"); //this isn't really necessary
writer.startblock();
writer.outputline(dest.getSafeSymbol() + " = !" + leftd.getSafeSymbol() + ";");
writer.endblock();
String lm = (VarDescriptor.makeNew("leftmaybe")).getSafeSymbol();
left.generate(writer, leftd);
writer.outputline("int " + lm + " = maybe;");
-
+ writer.outputline("maybe=0;");
VarDescriptor rightd = VarDescriptor.makeNew("rightboolean");
String rm = (VarDescriptor.makeNew("rightmaybe")).getSafeSymbol();
assert right != null;
* 1110 1 X
* 1111 1 X
*
- * M = (L*RM) + (R*LM) + (LM*RM)
+ * M = (L*RM) + (R*LM) + (LM*RM)
* O = (L*R)
*/
VarDescriptor ld = VarDescriptor.makeNew("leftop");
left.generate(writer, ld);
VarDescriptor rd = null;
+ VarDescriptor lm=VarDescriptor.makeNew("lm");
+ VarDescriptor rm=VarDescriptor.makeNew("rm");
if (right != null) {
+ if ((opcode==Opcode.OR)||
+ (opcode==Opcode.AND)) {
+ writer.outputline("int "+lm.getSafeSymbol()+"=maybe;");
+ writer.outputline("int maybe=0;");
+ }
+
rd = VarDescriptor.makeNew("rightop");
right.generate(writer, rd);
}
assert rd != null;
writer.outputline("int " + dest.getSafeSymbol() + " = " +
ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
- } else {
+ } else if (opcode == Opcode.AND) {
+ writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+ writer.outputline("maybe = (" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (" + rd.getSafeSymbol() + " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
+ writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " && " + rd.getSafeSymbol() + ";");
+ } else if (opcode == Opcode.OR) {
+ writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+ writer.outputline("maybe = (!" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (!" + rd.getSafeSymbol() +
+ " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
+ writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() +
+ ";");
+ } else {
writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
}
}
togenerate.addAll(termination.conjunctions);
togenerate.removeAll(removed);
GraphNode.computeclosure(togenerate,removed);
-
cost=new Cost();
sources=new Sources(state);
Repair.repairgenerator=this;
}
+ private void generatetypechecks(boolean flag) {
+ if (flag) {
+ DotExpr.DOTYPECHECKS=true;
+ VarExpr.DOTYPECHECKS=true;
+ DotExpr.DONULL=true;
+ VarExpr.DONULL=true;
+ } else {
+ VarExpr.DOTYPECHECKS=false;
+ DotExpr.DOTYPECHECKS=false;
+ VarExpr.DONULL=true;
+ DotExpr.DONULL=true;
+ }
+ }
+
+
private void name_updates() {
int count=0;
for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
this.outputhead = new java.io.PrintWriter(outputhead, true);
headername=st;
name_updates();
-
+ generatetypechecks(true);
generate_tokentable();
generate_hashtables();
generate_stateobject();
CodeWriter craux = new StandardCodeWriter(this.outputaux);
crhead.outputline("};");
craux.outputline("}");
+ generatetypechecks(false);
+ generate_computesizes();
+ generatetypechecks(true);
+ generate_recomputesizes();
+ generatetypechecks(false);
generate_updates();
+ StructureGenerator sg=new StructureGenerator(state,this);
+ sg.buildall();
+ crhead.outputline("#endif");
}
String ststate="state";
craux.outputline("void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+")");
}
craux.startblock();
+ craux.outputline("int maybe=0;");
final SymbolTable st = un.getRule().getSymbolTable();
CodeWriter cr = new StandardCodeWriter(outputaux) {
public SymbolTable getSymbolTable() { return st; }
};
un.generate(cr, false, stleft,stright,this);
+ craux.outputline("if (maybe) printf(\"REALLY BAD\");");
craux.endblock();
break;
case MultUpdateNode.REMOVE:
crhead.outputline(methodcall+";");
craux.outputline(methodcall);
craux.startblock();
+ craux.outputline("int maybe=0;");
final SymbolTable st2 = un.getRule().getSymbolTable();
CodeWriter cr2 = new StandardCodeWriter(outputaux) {
public SymbolTable getSymbolTable() { return st2; }
};
un.generate(cr2, true, null,null,this);
+ craux.outputline("if (maybe) printf(\"REALLY BAD\");");
craux.endblock();
break;
case MultUpdateNode.MODIFY:
VarDescriptor vd=(VarDescriptor) globals.next();
crhead.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+";");
}
+ crhead.outputline("void computesizes(int *,int **);");
+ crhead.outputline("void recomputesizes();");
+ }
+
+ private void generate_computesizes() {
+ int max=TypeDescriptor.counter;
+ TypeDescriptor[] tdarray=new TypeDescriptor[max];
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ tdarray[ttd.getId()]=ttd;
+ }
+ CodeWriter cr=new StandardCodeWriter(outputaux);
+ cr.outputline("void "+name+"_state::computesizes(int *sizearray,int **numele) {");
+ for(int i=0;i<max;i++) {
+ TypeDescriptor td=tdarray[i];
+ Expr size=td.getSizeExpr();
+ VarDescriptor vd=VarDescriptor.makeNew("size");
+ size.generate(cr,vd);
+ cr.outputline("sizearray["+i+"]="+vd.getSafeSymbol()+";");
+ }
+ for(int i=0;i<max;i++) {
+ TypeDescriptor td=tdarray[i];
+ if (td instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) td;
+ for(int j=0;j<std.fieldlist.size();j++) {
+ FieldDescriptor fd=(FieldDescriptor)std.fieldlist.get(j);
+ if (fd instanceof ArrayDescriptor) {
+ ArrayDescriptor ad=(ArrayDescriptor)fd;
+ Expr index=ad.getIndexBound();
+ VarDescriptor vd=VarDescriptor.makeNew("index");
+ index.generate(cr,vd);
+ cr.outputline("numele["+i+"]["+j+"]="+vd.getSafeSymbol()+";");
+ }
+ }
+ }
+ }
+ cr.outputline("}");
}
+ private void generate_recomputesizes() {
+ int max=TypeDescriptor.counter;
+ TypeDescriptor[] tdarray=new TypeDescriptor[max];
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ tdarray[ttd.getId()]=ttd;
+ }
+ CodeWriter cr=new StandardCodeWriter(outputaux);
+ cr.outputline("void "+name+"_state::recomputesizes() {");
+ for(int i=0;i<max;i++) {
+ TypeDescriptor td=tdarray[i];
+ Expr size=td.getSizeExpr();
+ VarDescriptor vd=VarDescriptor.makeNew("size");
+ size.generate(cr,vd);
+ }
+ for(int i=0;i<max;i++) {
+ TypeDescriptor td=tdarray[i];
+ if (td instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) td;
+ for(int j=0;j<std.fieldlist.size();j++) {
+ FieldDescriptor fd=(FieldDescriptor)std.fieldlist.get(j);
+ if (fd instanceof ArrayDescriptor) {
+ ArrayDescriptor ad=(ArrayDescriptor)fd;
+ Expr index=ad.getIndexBound();
+ VarDescriptor vd=VarDescriptor.makeNew("index");
+ index.generate(cr,vd);
+ }
+ }
+ }
+ }
+ cr.outputline("}");
+ }
+
+
private void generate_hashtables() {
CodeWriter craux = new StandardCodeWriter(outputaux);
CodeWriter crhead = new StandardCodeWriter(outputhead);
+ crhead.outputline("#ifndef "+name+"_h");
+ crhead.outputline("#define "+name+"_h");
crhead.outputline("#include \"SimpleHash.h\"");
+ crhead.outputline("extern \"C\" {");
+ crhead.outputline("#include \"instrument.h\"");
+ crhead.outputline("}");
crhead.outputline("#include <stdio.h>");
crhead.outputline("#include <stdlib.h>");
crhead.outputline("class "+name+" {");
crhead.outputline(name+"();");
crhead.outputline("~"+name+"();");
craux.outputline("#include \""+headername+"\"");
+ craux.outputline("#include \"size.h\"");
craux.outputline(name+"::"+name+"() {");
craux.outputline("// creating hashtables ");
repairtable=VarDescriptor.makeNew("repairtable");
crhead.outputline("void doanalysis();");
craux.outputline("void "+name +"_state::doanalysis()");
- craux.startblock();
+ craux.startblock();
+ craux.outputline("typeobject *typeobject1=gettypeobject();");
+ craux.outputline("typeobject1->computesizes(this);");
+ craux.outputline("recomputesizes();");
craux.outputline(name+ " * "+oldmodel.getSafeSymbol()+"=0;");
craux.outputline("WorkList * "+worklist.getSafeSymbol()+" = new WorkList();");
craux.outputline("RepairHash * "+repairtable.getSafeSymbol()+"=0;");
};
cr.outputline("// build " +escape(rule.toString()));
cr.startblock();
+ cr.outputline("int maybe=0;");
ListIterator quantifiers = rule.quantifiers();
while (quantifiers.hasNext()) {
Quantifier quantifier = (Quantifier) quantifiers.next();
quantifier.generate_open(cr);
}
-
+
/* pretty print! */
cr.output("//");
rule.getGuardExpr().prettyPrint(cr);
cr.indent();
cr.outputline(elseladder + " ("+idvar.getSafeSymbol()+" == " + dispatchid + ")");
cr.startblock();
+ cr.outputline("int maybe=0;");
VarDescriptor typevar=VarDescriptor.makeNew("type");
VarDescriptor leftvar=VarDescriptor.makeNew("left");
VarDescriptor rightvar=VarDescriptor.makeNew("right");
cr.outputline("switch("+mincostindex.getSafeSymbol()+") {");
for(int j=0;j<dnfconst.size();j++) {
Conjunction conj=dnfconst.get(j);
- GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj); if (removed.contains(gn))
+ GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj);
+ if (removed.contains(gn))
continue;
cr.outputline("case "+j+":");
for(int k=0;k<conj.size();k++) {
cr.endblock();
}
/* Update model */
-
cr.outputline("break;");
}
cr.outputline("}");
cr.outputline("delete "+oldmodel.getSafeSymbol()+";");
cr.outputline("delete "+newmodel.getSafeSymbol()+";");
cr.outputline("delete "+worklist.getSafeSymbol()+";");
+ cr.outputline("resettypemap();");
cr.outputline("break;");
cr.endblock();
cr.outputline("rebuild:");
cr.outputline("");
}
}
- }
+ }
private MultUpdateNode getmultupdatenode(Conjunction conj, DNFPredicate dpred, int repairtype) {
MultUpdateNode mun=null;
cr.endblock();
}
}
-
-
-
public String getSafeSymbol() {
return getSymbol();
}
-
}
return false;
}
- stGlobals.add(new VarDescriptor(name, name, td));
+ stGlobals.add(new VarDescriptor(name, name, td,true));
return true;
}
--- /dev/null
+package MCC.IR;
+
+import java.io.*;
+import java.util.*;
+import MCC.State;
+
+public class StructureGenerator {
+ State state;
+ CodeWriter cr;
+ CodeWriter crhead;
+ TypeDescriptor[] tdarray;
+ RepairGenerator rg;
+ StructureGenerator(State state, RepairGenerator rg) {
+ this.state=state;
+ this.rg=rg;
+ try {
+ cr=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.cc"),true));
+ crhead=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.h"),true));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void buildall() {
+ int max=TypeDescriptor.counter;
+ tdarray=new TypeDescriptor[max];
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ tdarray[ttd.getId()]=ttd;
+ }
+ cr.outputline("#include \"size.h\"");
+ generategetfield();
+ generategetnumfields();
+ generateisArray();
+ generateisPtr();
+ generateissubtype();
+ generatecalls();
+ generatecomputesize();
+ generateheader();
+ }
+
+ private void generatecalls() {
+ int max=TypeDescriptor.counter;
+ cr.outputline("int arsize["+max+"];");
+
+ for(int i=0;i<max;i++) {
+ TypeDescriptor ttd=tdarray[i];
+ if (ttd instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+ String str="int arnumelement"+std.getId()+"["+std.fieldlist.size()+"]={";
+ for(int j=0;j<std.fieldlist.size();j++) {
+ str+=0;
+ if (((j+1)!=std.fieldlist.size()))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+ } else
+ cr.outputline("int arnumelement"+ttd.getId()+"[0];");
+ }
+ String str="int* arnumelements["+String.valueOf(max)+"]={";
+ for(int i=0;i<max;i++) {
+ str+="arnumelement"+i;
+ if (((i+1)!=max))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+
+
+ cr.outputline("int typeobject::size(int type) {");
+ cr.outputline("return arsize[type];");
+ cr.outputline("}");
+
+ cr.outputline("int typeobject::numElements(int type, int fieldindex) {");
+ cr.outputline("return arnumelements[type][fieldindex];");
+ cr.outputline("}");
+ cr.outputline("typeobject::typeobject() {}");
+ }
+
+ private void generatecomputesize() {
+ int max=TypeDescriptor.counter;
+ cr.outputline("void typeobject::computesizes("+rg.name+"_state * obj) {");
+ cr.outputline("obj->computesizes(arsize,arnumelements);");
+ cr.outputline("}");
+ }
+
+ private void generateheader() {
+ crhead.outputline("#include \""+rg.headername + "\"");
+ crhead.outputline("class typeobject {");
+ crhead.outputline("public:");
+ crhead.outputline("typeobject();");
+ crhead.outputline("int getfield(int type, int fieldindex);");
+ crhead.outputline("int isArray(int type, int fieldindex);");
+ crhead.outputline("int isPtr(int type, int fieldindex);");
+ crhead.outputline("int numElements(int type, int fieldindex);");
+ crhead.outputline("int size(int type);");
+ crhead.outputline("int getnumfields(int type);");
+ crhead.outputline("bool issubtype(int subtype, int type);");
+ crhead.outputline("void computesizes("+rg.name+"_state *);");
+ crhead.outputline("};");
+ }
+
+
+ private void generategetfield() {
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ String str="";
+
+ if (ttd instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+ str="int argetfield"+std.getId()+"["+std.fieldlist.size()+"]={";
+ for(int i=0;i<std.fieldlist.size();i++) {
+ FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+ TypeDescriptor td = fd.getType();
+ str+=String.valueOf(td.getId());
+ if ((i+1)!=std.fieldlist.size())
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+ } else
+ cr.outputline("int argetfield"+ttd.getId()+"[0];");
+ }
+ int max=TypeDescriptor.counter;
+ String str="int* argetfield["+String.valueOf(max)+"]={";
+ for(int i=0;i<max;i++) {
+ str+="argetfield"+i;
+ if (((i+1)!=max))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+
+ cr.outputline("int typeobject::getfield(int type, int fieldindex) {");
+ cr.outputline("return argetfield[type][fieldindex];");
+ cr.outputline("}");
+ }
+
+ private void generategetnumfields() {
+ int max=TypeDescriptor.counter;
+ String str="int argetnumfield["+String.valueOf(max)+"]={";
+ for(int i=0;i<max;i++) {
+ TypeDescriptor ttd=tdarray[i];
+ if (ttd instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+ str+=String.valueOf(std.fieldlist.size());
+ } else
+ str+="0";
+ if (((i+1)!=max))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+
+ cr.outputline("int typeobject::getnumfields(int type) {");
+ cr.outputline("return argetnumfield[type];");
+ cr.outputline("}");
+ }
+ private void generateisArray() {
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ String str="";
+
+ if (ttd instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+ str="int arisArray"+std.getId()+"["+std.fieldlist.size()+"]={";
+ for(int i=0;i<std.fieldlist.size();i++) {
+ FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+ TypeDescriptor td = fd.getType();
+ if (fd instanceof ArrayDescriptor)
+ str+="1";
+ else
+ str+="0";
+ if ((i+1)!=std.fieldlist.size())
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+ } else
+ cr.outputline("int arisArray"+ttd.getId()+"[0];");
+ }
+ int max=TypeDescriptor.counter;
+ String str="int* arisArray["+String.valueOf(max)+"]={";
+ for(int i=0;i<max;i++) {
+ str+="arisArray"+i;
+ if (((i+1)!=max))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+
+ cr.outputline("int typeobject::isArray(int type, int fieldindex) {");
+ cr.outputline("return arisArray[type][fieldindex];");
+ cr.outputline("}");
+ }
+ private void generateisPtr() {
+ for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
+ TypeDescriptor ttd=(TypeDescriptor)it.next();
+ String str="";
+
+ if (ttd instanceof StructureTypeDescriptor) {
+ StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
+ str="int arisPtr"+std.getId()+"["+std.fieldlist.size()+"]={";
+ for(int i=0;i<std.fieldlist.size();i++) {
+ FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
+ if (fd.getPtr())
+ str+="1";
+ else
+ str+="0";
+ if ((i+1)!=std.fieldlist.size())
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+ } else
+ cr.outputline("int arisPtr"+ttd.getId()+"[0];");
+ }
+ int max=TypeDescriptor.counter;
+ String str="int* arisPtr["+String.valueOf(max)+"]={";
+ for(int i=0;i<max;i++) {
+ str+="arisPtr"+i;
+ if (((i+1)!=max))
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+
+ cr.outputline("int typeobject::isPtr(int type, int fieldindex) {");
+ cr.outputline("return arisPtr[type][fieldindex];");
+ cr.outputline("}");
+ }
+
+ void generateissubtype() {
+ int max=TypeDescriptor.counter;
+ String str="bool arissubtype["+max+"]["+max+"]={";
+ for(int i=0;i<max;i++) {
+ str+="{";
+ for(int j=0;j<max;j++) {
+ TypeDescriptor tdi=tdarray[i];
+ TypeDescriptor tdj=tdarray[j];
+ if (tdi.isSubtypeOf(tdj))
+ str+="1";
+ else
+ str+="0";
+ if ((j+1)!=max)
+ str+=",";
+ }
+ str+="}";
+ if ((i+1)!=max)
+ str+=",";
+ }
+ str+="};";
+ cr.outputline(str);
+ cr.outputline("bool typeobject::issubtype(int subtype, int type) {");
+ cr.outputline("return arissubtype[subtype][type];");
+ cr.outputline("}");
+ }
+}
Hashtable fields = new Hashtable(); /* fast lookups */
Vector fieldlist = new Vector(); /* ordering information */
Hashtable labels = new Hashtable();
- int idnum;
- static int counter=0;
- public int getId() {
- return idnum;
- }
public StructureTypeDescriptor(String name) {
super(name);
- idnum=counter++;
}
public TypeDescriptor getGenerateType() {
if (td == this) {
return true;
} else {
+ if (subtype==null)
+ return false;
return subtype.isSubtypeOf(td);
}
}
*/
public abstract class TypeDescriptor extends Descriptor {
+ static int counter=0;
+ int idnum;
+
+ public int getId() {
+ return idnum;
+ }
public TypeDescriptor(String name) {
super(name);
+ if (!(this instanceof MissingTypeDescriptor))
+ idnum=counter++;
}
public boolean isSubtypeOf(TypeDescriptor td) {
public class VarDescriptor extends Descriptor {
private static int count = 0;
+ boolean isglobal=false;
TypeDescriptor td = null;
this.td = td;
}
- public VarDescriptor(String name, String safename, TypeDescriptor td) {
+ public VarDescriptor(String name, String safename, TypeDescriptor td, boolean global) {
super(name, safename);
this.td = td;
+ this.isglobal=global;
}
+ public boolean isGlobal() {
+ return isglobal;
+ }
+
public void setType(TypeDescriptor td) {
this.td = td;
}
import java.util.*;
public class VarExpr extends Expr {
+ static boolean DOMEMCHECKS=true;
+ static boolean DOTYPECHECKS=false;
+ static boolean DONULL=false;
String varname;
VarDescriptor vd = null;
assert vd.getType() != null;
this.td = vd.getType();
+
writer.outputline(vd.getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() +
" = (" + vd.getType().getGenerateType().getSafeSymbol() + ") " + vd.getSafeSymbol() + "; //varexpr");
+ if (vd.isGlobal() && (DOTYPECHECKS||DOMEMCHECKS) && (td instanceof StructureTypeDescriptor)) {
+ VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
+ if (DOTYPECHECKS)
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+ else
+ writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + td.getId() + ");");
+ writer.outputline("if (!"+typevar.getSafeSymbol()+")");
+ writer.startblock();
+ writer.outputline(dest.getSafeSymbol()+"=0;");
+ if (DONULL)
+ writer.outputline(vd.getSafeSymbol()+"=0;");
+ writer.endblock();
+ }
}
public void prettyPrint(PrettyPrinter pp) {