small changes
[repair.git] / Repair / RepairCompiler / MCC / CRuntime / tmap.c
1 #include <stdio.h>
2 #include "tmap.h"
3 #include "size.h"
4 #include "stack.h"
5 #include <stdlib.h>
6
7 #ifndef COMMANDLINEFLAGS
8 #define CHECKTYPE
9 #define CHECKMEMORY
10 #endif
11
12 struct typemap * allocatetypemap() {
13   struct typemap *thisvar=(struct typemap *) malloc(sizeof(struct typemap));
14 #ifdef CHECKTYPE||CHECKMEMORY
15   thisvar->alloctree=rbinit();
16   thisvar->typetree=rbinit();
17   thisvar->low=GC_linux_stack_base();
18 #endif
19   return thisvar;
20 }
21
22 void freefunction(void *ptr) {
23   if(ptr!=NULL) {
24     freestructuremap((struct structuremap *)ptr);
25   }
26 }
27
28 void freetypemap(struct typemap * ptr) {
29   rbdestroy(ptr->typetree,freefunction);
30   rbdestroy(ptr->alloctree,freefunction);
31   free(ptr);
32 }
33
34 void typemapreset(struct typemap *ptr) {
35   rbdestroy(ptr->typetree,freefunction);
36   ptr->typetree=rbinit();
37   if (ptr->low<ptr->high)
38     rbdelete(ptr->low,ptr->alloctree);
39   else
40     rbdelete(ptr->high,ptr->alloctree);
41 }
42
43 void initializetypemapstack(struct typemap * ptr, void *high) {
44   ptr->high=high;
45   if (ptr->low<ptr->high)
46     rbinsert(ptr->low,ptr->high,NULL,ptr->alloctree);
47   else
48     rbinsert(ptr->high,ptr->low,NULL,ptr->alloctree);
49 }
50
51 struct structuremap * allocatestructuremap(int s) {
52   struct structuremap *ptr=(struct structuremap *)malloc(sizeof(struct structuremap));
53   ptr->str=s;
54   ptr->typetree=rbinit();
55   return ptr;
56 }
57
58 void freestructuremap(struct structuremap *ptr) {
59   rbdestroy(ptr->typetree,freefunction);
60   free(ptr);
61 }
62
63 bool typemapasserttype(struct typemap *thisvar, void *ptr, int s) {
64   int toadd=sizeBytes(s);
65   return typemapasserttypeB(thisvar, ptr,((char *) ptr)+toadd,s);
66 }
67
68 bool typemapasserttypeB(struct typemap * thisvar, void *ptr, void *high, int s) {
69 #ifdef CHECKTYPE
70   bool b=typemapchecktype(thisvar,true,ptr,s);
71   if (!b) {
72     printf("Assertion failure\n");
73     {
74       bool testb=typemapchecktype(thisvar,true,ptr,s);
75     }
76   }
77   return b;
78 #endif
79   return typemapassertvalidmemoryB(thisvar,ptr, high);
80 }
81
82 bool typemapassertvalidmemory(struct typemap * thisvar, void* low, int s) {
83   int toadd=sizeBytes(s);
84   return typemapassertvalidmemoryB(thisvar, low,((char *)low)+toadd);
85 }
86
87 bool typemapassertexactmemory(struct typemap * thisvar, void* low, int s) {
88   int toadd=sizeBytes(s);
89 #ifdef CHECKMEMORY
90   {
91     void * high=((char *)low)+toadd;
92     struct pair allocp=rbfind(low,high,thisvar->alloctree);
93     if (allocp.low == NULL) {
94       return false;
95     } else if ((allocp.low != low) || (allocp.high != high)) {
96     /* make sure this block exactly lines up */
97       return false;
98     } else {
99       return true;
100     }
101   }
102 #else
103   return true;
104 #endif
105 }
106
107 bool typemapassertvalidmemoryB(struct typemap * thisvar, void* low, void* high) {
108 #ifdef CHECKMEMORY
109   return typemapcheckmemory(thisvar, low, high);
110 #endif
111   return true;
112 }
113
114 bool typemapistype(struct typemap *thisvar, void *ptr, void *high, int s) {
115 #ifdef CHECKTYPE
116   bool b=typemapchecktype(thisvar, false,ptr,s);
117   if (!b) {
118     printf("Verify failure\n");
119     {
120       bool testb=typemapchecktype(thisvar, false,ptr,s);
121     }
122   }
123   return b;
124 #endif
125   return typemapassertvalidmemoryB(thisvar, ptr, high);
126 }
127
128 void typemapallocate(struct typemap *thisvar,void *ptr, int size) {
129   void *low=ptr;
130   void *high=((char *)ptr)+size;
131   int val=rbinsert(low,high,NULL,thisvar->alloctree);
132   if (val==0)
133     printf("Error\n");
134 }
135
136 inline int sizeinbytes(unsigned int bits) {
137   int bytes=bits>>3;
138   if (bits %8)
139     bytes++;
140   return bytes;
141 }
142
143 int typemapfindoffsetstructure(struct typemap * thisvar, int s, int offset) {
144   int count=0;
145   int i;
146   int increment;
147   for(i=0;i<getnumfields(s);i++) {
148     int mult=1;
149     int ttype=getfield(s,i);
150     if (isArray(s,i)) {
151       mult=numElements(s,i);
152     }
153     increment=size(ttype);
154     if (increment%8) {
155       int delt=offset-count;
156       int byteincrement=increment/8;
157       if (delt<mult*byteincrement) {
158         if (delt%byteincrement==0) {
159           return ttype;
160         } else
161           return -1;
162       }
163     } else {
164       if ((count+sizeinbytes(mult*increment))>offset)
165         return -1;
166     }
167     count+=sizeinbytes(mult*increment);
168   }
169   return -1;
170 }
171
172 void typemapdeallocate(struct typemap * thisvar,void *ptr) {
173   if (rbdelete(ptr,thisvar->alloctree)==NULL)
174     printf("Freeing unallocated memory\n");
175 }
176
177 bool typemapcheckmemory(struct typemap *thisvar, void* low, void* high) {
178   struct pair allocp=rbfind(low,high,thisvar->alloctree);
179   if (allocp.low == NULL) {
180     return false;
181   } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */
182     return false;
183   } else {
184     return true;
185   }
186 }
187
188 void * typemapgetendofblock(struct typemap *thisvar, void* low) {
189   struct pair allocp=rbfind(low,((char*)low)+1,thisvar->alloctree);
190   if (allocp.low == NULL) {
191     return NULL;
192   } else if ((allocp.low > low)||(allocp.high <= allocp.low)) { /* make sure this block is used */
193     return NULL;
194   } else {
195     return (void *)allocp.high;
196   }
197 }
198
199
200 bool typemapchecktype(struct typemap *thisvar, bool doaction,void *ptr, int structure) {
201   int ssize=sizeBytes(structure);
202   void *low=ptr;
203   void *high=((char *)low)+ssize;
204   struct pair allocp=rbfind(low,high,thisvar->alloctree);
205   if (allocp.low==NULL)
206     return false;
207   if (allocp.low>low||allocp.high<high) /* make sure this block is used */
208     return false;
209   {
210     struct pair typep=rbfind(low,high,thisvar->typetree);
211     struct structuremap *smap=(struct structuremap *)rblookup(low,high,thisvar->typetree);
212     if (typep.low==NULL) {
213       if(!doaction)
214         return true;
215       {
216         struct structuremap *sm=allocatestructuremap(structure);
217         int flag=rbinsert(low, high, sm, thisvar->typetree);
218         if (flag==0) {
219           printf("Error in asserttype\n");
220           return false;
221         } else
222           return true;
223       }
224     }
225     return typemapchecktypeB(thisvar, doaction, low,high, structure, thisvar->typetree);
226   }
227 }
228
229 bool typemapchecktypeB(struct typemap *thisvar, bool doaction, void *low, void *high, int structure, struct rbtree *ttree) {
230   struct pair typep=rbfind(low,high,ttree);
231   struct structuremap *smap=(struct structuremap *)rblookup(low,high,ttree);
232   if (typep.low==low&&typep.high==high) {
233     /* Recast */
234     if (issubtype(structure,smap->str)) {
235       /* narrowing cast */
236       if (!doaction)
237         return true;
238       smap->str=structure;
239       return true;
240     } else if (issubtype(smap->str,structure)) {
241       /* widening cast */
242       return true;
243     } else
244       return false; /* incompatible types */
245   } else if (typep.low<=low&&typep.high>=high) {
246     /* See if it matches up with structure inside typep */
247     if (rbsearch(low,high,smap->typetree)) {
248       /* recurse */
249       return typemapchecktypeB(thisvar,doaction,low,high, structure, smap->typetree);
250     } else {
251       /* check to see if data lines up correctly */
252       int offset=((char *)low)-((char *)typep.low);
253       int st=typemapfindoffsetstructure(thisvar, smap->str,offset);
254       if (st==-1)
255         return false;
256       if (issubtype(structure,st)) {
257         if (!doaction)
258           return true;
259         {
260           struct structuremap *newsm=allocatestructuremap(structure);
261           int flag=rbinsert(low, high, newsm, smap->typetree);
262           return (flag==1);
263         }
264       } else if (issubtype(st,structure)) {
265         if (!doaction)
266           return true;
267         {
268           struct structuremap *newsm=allocatestructuremap(st);
269           int flag=rbinsert(low, high, newsm, smap->typetree);
270           return (flag==1);
271         }
272       } else
273         return false;
274     }
275   } else
276     return false;
277 }