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