Committing changes to leftsize->rightSize, more comments, and handling
[repair.git] / Repair / RepairCompiler / MCC / IR / DotExpr.java
index 901b523d2b7730348490b26cd63b8c9c1e0c4d48..1c5fb47f0055c7ec9c88d7d9b599a21e390939f0 100755 (executable)
@@ -7,6 +7,30 @@ public class DotExpr extends Expr {
     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;
@@ -23,26 +47,41 @@ public class DotExpr extends Expr {
     FieldDescriptor fd;
     TypeDescriptor fieldtype;
     Expr intindex;
+
+    public String name() {
+       String name=left.name()+"."+field;
+       if (index!=null)
+           name+="["+index.name()+"]";
+       return name;
+    }
+    
+    public boolean usesDescriptor(Descriptor d) {
+       if (d==fd)
+           return true;
+       return left.usesDescriptor(d)||((intindex!=null)&&intindex.usesDescriptor(d));
+    }
+
+    public boolean equals(Map remap, Expr e) {
+       if (e==null||!(e instanceof DotExpr))
+           return false;
+       DotExpr de=(DotExpr)e;
+       if (!de.field.equals(field))
+           return false;
+       if (index==null) {
+           if (de.index!=null)
+               return false;
+       } else if (!index.equals(remap,de.index))
+           return false;
+       if (!left.equals(remap,de.left))
+           return false;
+       return true;
+    }
+
     
     public DotExpr(Expr left, String field, Expr index) {
         this.left = left;
         this.field = field;
         this.index = index;
-        StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();        
-        FieldDescriptor fd = struct.getField(field);
-        LabelDescriptor ld = struct.getLabel(field);
-       if (ld != null) { /* label */
-            assert fd == null;
-            fieldtype = ld.getType(); // d.s ==> Superblock, while,  d.b ==> Block
-            fd = ld.getField();
-            assert fd != null;
-            assert intindex == null;
-            intindex = ld.getIndex();
-        } else {
-            fieldtype = fd.getType();
-           intindex=index;
-        }
-       this.fd=fd;
     }
 
     public Set getRequiredDescriptors() {
@@ -79,52 +118,43 @@ public class DotExpr extends Expr {
         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) {
@@ -136,20 +166,40 @@ public class DotExpr extends Expr {
                 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");
@@ -172,48 +222,43 @@ public class DotExpr extends Expr {
                 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) {
@@ -237,9 +282,32 @@ public class DotExpr extends Expr {
         }
     }
 
+    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);
+       
+       {
+           /* finished typechecking...so we can fill the fields in */
+           StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();        
+           FieldDescriptor fd = struct.getField(field);
+           LabelDescriptor ld = struct.getLabel(field);
+           if (ld != null) { /* label */
+               assert fd == null;
+               fieldtype = ld.getType(); // d.s ==> Superblock, while,  d.b ==> Block
+               fd = ld.getField();
+               assert fd != null;
+               assert intindex == null;
+               intindex = ld.getIndex();
+           } else {
+               fieldtype = fd.getType();
+               intindex=index;
+           }
+           this.fd=fd;
+       }
 
         if ((lefttype == null) || (index != null && indextype == null)) {
             return null;
@@ -295,9 +363,6 @@ public class DotExpr extends Expr {
             sa.getErrorReporter().report(null, "Left hand side of . expression must be a structure type, not '" + lefttype.getSymbol() + "'");
             return null;
         }
-        
-        
     }
-
 }