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