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