2b626adccac35d87b97dd3dfcb15be878213740a
[repair.git] / Repair / RepairCompiler / MCC / Runtime / tmap.cc
1 #include <stdio.h>
2 #include "tmap.h"
3 #include "size.h"
4 extern "C" {
5 #include "libredblack/redblack.h"
6 }
7
8 #define CHECKTYPE
9 #define CHECKMEMORY
10
11 typemap::typemap(typeobject * size) {
12   alloctree=rbinit();
13   typetree=rbinit();
14   this->size=size;
15 }
16
17 void freefunction(void *ptr) {
18   if(ptr!=NULL) {
19     delete((structuremap *)ptr);
20   }
21 }
22
23 typemap::~typemap() {
24   rbdestroy(typetree,freefunction);
25   rbdestroy(alloctree,freefunction);
26 }
27
28 void typemap::reset() {
29   rbdestroy(typetree,freefunction);
30   typetree=rbinit();
31   size->reset();
32 }
33
34 structuremap::structuremap(int s) {
35   str=s;
36   typetree=rbinit();
37 }
38
39 structuremap::~structuremap() {
40   rbdestroy(typetree,freefunction);
41 }
42
43 bool typemap::asserttype(void *ptr, void *high, int s) {
44 #ifdef CHECKTYPE
45   bool b=checktype(true,ptr,s);
46   if (!b) {
47     printf("Assertion failure\n");
48     bool testb=checktype(true,ptr,s);
49   }
50   return b;
51 #endif
52   return assertvalidmemory(ptr, high);
53 }
54
55 bool typemap::assertvalidmemory(void* low, void* high) {
56 #ifdef CHECKMEMORY
57   return checkmemory(low, high);
58 #endif
59   return true;
60 }
61
62 bool typemap::istype(void *ptr, void *high, int s) {
63 #ifdef CHECKTYPE
64   bool b=checktype(false,ptr,s);
65   if (!b) {
66     printf("Verify failure\n");
67     bool testb=checktype(false,ptr,s);
68   }
69   return b;
70 #endif
71   return assertvalidmemory(ptr, high);
72 }
73
74 void typemap::allocate(void *ptr, int size) {
75   void *low=ptr;
76   void *high=((char *)ptr)+size;
77   int val=rbinsert(low,high,NULL,alloctree);
78   if (val==0)
79     printf("Error\n");
80 }
81
82 int typemap::findoffsetstructure(int s, int offset) {
83   int count=0;
84   for(int i=0;i<size->getnumfields(s);i++) {
85     int mult=1;
86     int ttype=size->getfield(s,i);
87     if (size->isArray(s,i)) {
88       mult=size->numElements(s,i);
89     }
90     int increment=size->size(ttype);
91     int delt=offset-count;
92     if (delt<mult*increment) {
93       if (delt%increment==0) {
94         return ttype;
95       } else
96         return -1;
97     }
98     count+=mult*increment;
99   }
100   return -1;
101 }
102
103 void typemap::deallocate(void *ptr) {
104   if (rbdelete(ptr,alloctree)==NULL)
105     printf("Freeing unallocated memory\n");
106 }
107
108 bool typemap::checkmemory(void* low, void* high) {
109   struct pair allocp=rbfind(low,high,alloctree);
110   if (allocp.low == NULL) {
111     return false; 
112   } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */
113     return false;
114   } else {
115     return true;
116   }
117 }
118
119
120 bool typemap::checktype(bool doaction,void *ptr, int structure) {
121   int ssize=size->size(structure);
122   void *low=ptr;
123   void *high=((char *)low)+ssize;
124   struct pair allocp=rbfind(low,high,alloctree);
125   if (allocp.low==NULL)
126     return false;
127   if (allocp.low>low||allocp.high<high) /* make sure this block is used */
128     return false;
129   struct pair typep=rbfind(low,high,typetree);
130   structuremap *smap=(structuremap *)rblookup(low,high,typetree);
131   if (typep.low==NULL) {
132     if(!doaction)
133       return true;
134     structuremap *sm=new structuremap(structure);
135     int flag=rbinsert(low, high, sm, typetree);
136     if (flag==0) {
137       printf("Error in asserttype\n");
138       return false;
139     } else
140       return true;
141   }
142   return checktype(doaction, low,high, structure, typetree);
143 }
144
145 bool typemap::checktype(bool doaction, void *low, void *high, int structure, struct rbtree *ttree) {
146   struct pair typep=rbfind(low,high,ttree);
147   structuremap *smap=(structuremap *)rblookup(low,high,ttree);
148   if (typep.low==low&&typep.high==high) {
149     /* Recast */
150     if (size->issubtype(structure,smap->str)) {
151       /* narrowing cast */
152       if (!doaction)
153         return true;
154       smap->str=structure;
155       return true;
156     } else if (size->issubtype(smap->str,structure)) {
157       /* widening cast */
158       return true;
159     } else
160       return false; /* incompatible types */
161   } else if (typep.low<=low&&typep.high>=high) {
162     /* See if it matches up with structure inside typep */
163     if (rbsearch(low,high,smap->typetree)) {
164       /* recurse */
165       return checktype(doaction,low,high, structure, smap->typetree);
166     } else {
167       /* check to see if data lines up correctly */
168       int offset=((char *)low)-((char *)typep.low);
169       int st=findoffsetstructure(smap->str,offset);
170       if (st==-1)
171         return false;
172       if (size->issubtype(structure,st)) {
173         if (!doaction)
174           return true;
175         structuremap *newsm=new structuremap(structure);
176         int flag=rbinsert(low, high, newsm, smap->typetree);
177         return (flag==1);
178       } else if (size->issubtype(st,structure)) {
179         if (!doaction)
180           return true;
181         structuremap *newsm=new structuremap(st);
182         int flag=rbinsert(low, high, newsm, smap->typetree);
183         return (flag==1);
184       } else
185         return false;
186     }
187   } else
188     return false;
189 }