Moved the interpreter
[repair.git] / Repair / RepairInterpreter / tmap.cc
diff --git a/Repair/RepairInterpreter/tmap.cc b/Repair/RepairInterpreter/tmap.cc
new file mode 100755 (executable)
index 0000000..f0ced38
--- /dev/null
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include "tmap.h"
+extern "C" {
+#include "redblack.h"
+}
+#include "tmodel.h"
+#include "model.h"
+#include "processabstract.h"
+#include "element.h"
+
+#define CHECKTYPE
+#define CHECKMEMORY
+
+typemap::typemap(model *m) {
+  alloctree=rbinit();
+  typetree=rbinit();
+  globalmodel=m;
+}
+
+void freefunction(void *ptr) {
+  if(ptr!=NULL) {
+    delete((structuremap *)ptr);
+  }
+}
+
+typemap::~typemap() {
+  rbdestroy(typetree,freefunction);
+  rbdestroy(alloctree,freefunction);
+}
+
+void typemap::reset() {
+  rbdestroy(typetree,freefunction);
+  typetree=rbinit();
+}
+
+structuremap::structuremap(structure *s) {
+  str=s;
+  typetree=rbinit();
+}
+
+structuremap::~structuremap() {
+  rbdestroy(typetree,freefunction);
+}
+
+bool typemap::asserttype(void *ptr, structure *s) {
+
+#ifdef CHECKTYPE
+  bool b=checktype(true,ptr,s);
+  if (!b) {
+    printf("Assertion failure\n");
+    bool testb=checktype(true,ptr,s);
+  }
+  return b;
+#endif
+
+  return assertvalidmemory(ptr, s);
+}
+
+bool typemap::assertvalidmemory(void* low, void* high) {
+
+#ifdef CHECKMEMORY
+  return checkmemory(low, high);
+#endif
+
+  return true;
+}
+
+bool typemap::assertvalidmemory(void* ptr, structure* s) {
+
+#ifdef CHECKMEMORY
+  int size=s->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+  void *low=ptr;
+  void *high=((char *)low)+size;
+  return checkmemory(low, high);
+#endif
+  
+  return true;
+}
+
+bool typemap::istype(void *ptr, structure *s) {
+
+#ifdef CHECKTYPE
+  bool b=checktype(false,ptr,s);
+  if (!b) {
+    printf("Verify failure\n");
+    bool testb=checktype(false,ptr,s);
+  }
+  return b;
+#endif
+
+  return assertvalidmemory(ptr, s);
+}
+
+void typemap::allocate(void *ptr, int size) {
+  void *low=ptr;
+  void *high=((char *)ptr)+size;
+  int val=rbinsert(low,high,NULL,alloctree);
+  if (val==0)
+    printf("Error\n");
+}
+
+structure * typemap::findoffsetstructure(structure *s, int offset) {
+  int count=0;
+  for(int i=0;i<s->getnumfields();i++) {
+    int mult=1;
+    ttype *ttype=s->getfield(i)->gettype();
+    if (ttype->getsize()!=NULL) {
+      Element * number=evaluateexpr(globalmodel,ttype->getsize(),globalmodel->gethashtable(),true,false);
+      mult=number->intvalue();
+      delete(number);
+    }
+    int increment=ttype->basesize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+
+    int delt=offset-count;
+    if (delt<mult*increment) {
+      if (delt%increment==0) {
+       return globalmodel->getstructure(ttype->getname());
+      } else
+       return NULL;
+    }
+
+    count+=mult*increment;
+  }
+  
+  return NULL;
+}
+
+void typemap::deallocate(void *ptr) {
+  if (rbdelete(ptr,alloctree)==NULL)
+    printf("Freeing unallocated memory\n");
+}
+
+bool typemap::checkmemory(void* low, void* high) {
+  struct pair allocp=rbfind(low,high,alloctree);
+
+  if (allocp.low == NULL) {
+      return false; 
+  } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */
+      return false;
+  } else {
+      return true;
+  }
+}
+
+
+bool typemap::checktype(bool doaction,void *ptr, structure *structure) {
+  int size=structure->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+  void *low=ptr;
+  void *high=((char *)low)+size;
+  struct pair allocp=rbfind(low,high,alloctree);
+  if (allocp.low==NULL)
+    return false;
+  if (allocp.low>low||allocp.high<high) /* make sure this block is used */
+    return false;
+  struct pair typep=rbfind(low,high,typetree);
+  structuremap *smap=(structuremap *)rblookup(low,high,typetree);
+  
+  if (typep.low==NULL) {
+    if(!doaction)
+      return true;
+    structuremap *sm=new structuremap(structure);
+    int flag=rbinsert(low, high, sm, typetree);
+    if (flag==0) {
+      printf("Error in asserttype\n");
+      return false;
+    } else
+      return true;
+  }
+
+  return checktype(doaction, low,high, structure, typetree);
+}
+
+bool typemap::checktype(bool doaction, void *low, void *high,structure *structre, struct rbtree *ttree) {
+  struct pair typep=rbfind(low,high,ttree);
+  structuremap *smap=(structuremap *)rblookup(low,high,ttree);
+  
+  if (typep.low==low&&typep.high==high) {
+    /* Recast */
+    if (globalmodel->subtypeof(structre,smap->str)) {
+      /* narrowing cast */
+      if (!doaction)
+       return true;
+      smap->str=structre;
+      return true;
+    } else if (globalmodel->subtypeof(smap->str,structre)) {
+      /* widening cast */
+      return true;
+    } else
+      return false; /* incompatible types */
+  } else if (typep.low<=low&&typep.high>=high) {
+    /* See if it matches up with structure inside typep */
+    if (rbsearch(low,high,smap->typetree)) {
+      /* recurse */
+      return checktype(doaction,low,high, structre, smap->typetree);
+    } else {
+      /* check to see if data lines up correctly */
+      int offset=((char *)low)-((char *)typep.low);
+      structure * st=findoffsetstructure(smap->str,offset);
+      if (st==NULL)
+       return false;
+      if (globalmodel->subtypeof(structre,st)) {
+       if (!doaction)
+         return true;
+       structuremap *newsm=new structuremap(structre);
+       int flag=rbinsert(low, high, newsm, smap->typetree);
+       return (flag==1);
+      } else if (globalmodel->subtypeof(st,structre)) {
+       if (!doaction)
+         return true;
+       structuremap *newsm=new structuremap(st);
+       int flag=rbinsert(low, high, newsm, smap->typetree);
+       return (flag==1);
+      } else
+       return false;
+    }
+  } else
+    return false;
+}