Added support for stack allocation. Check for NULL before calling memory checker.
[repair.git] / Repair / RepairCompiler / MCC / IR / StructureGenerator.java
1 package MCC.IR;
2
3 import java.io.*;
4 import java.util.*;
5 import MCC.State;
6
7 public class StructureGenerator {
8     State state;
9     CodeWriter cr;
10     CodeWriter crhead;
11     TypeDescriptor[] tdarray;
12     RepairGenerator rg;
13     StructureGenerator(State state, RepairGenerator rg) {
14         this.state=state;
15         this.rg=rg;
16         try {
17             cr=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.cc"),true));
18             crhead=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.h"),true));
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23
24     void buildall() {
25         int max=TypeDescriptor.counter;
26         tdarray=new TypeDescriptor[max];
27         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
28             TypeDescriptor ttd=(TypeDescriptor)it.next();
29             tdarray[ttd.getId()]=ttd;
30         }
31         cr.outputline("#include \"size.h\"");
32         generategetfield();
33         generategetnumfields();
34         generateisArray();
35         generateisPtr();
36         generateissubtype();
37         generatecalls();
38         generatecomputesize();
39         generateheader();
40     }
41
42     private void generatecalls() {
43         int max=TypeDescriptor.counter;
44         cr.outputline("int arsize["+max+"];");
45         cr.outputline("int arsizeBytes["+max+"];");
46
47         for(int i=0;i<max;i++) {
48             TypeDescriptor ttd=tdarray[i];
49             if (ttd instanceof StructureTypeDescriptor) {
50                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
51                 String str="int arnumelement"+std.getId()+"["+std.fieldlist.size()+"]={";
52                 for(int j=0;j<std.fieldlist.size();j++) {
53                     str+=0;
54                     if (((j+1)!=std.fieldlist.size()))
55                         str+=",";
56                 }
57                 str+="};";
58                 cr.outputline(str);
59             } else
60                 cr.outputline("int arnumelement"+ttd.getId()+"[0];");
61         }
62         String str="int* arnumelements["+String.valueOf(max)+"]={";
63         for(int i=0;i<max;i++) {
64             str+="arnumelement"+i;
65             if (((i+1)!=max))
66                 str+=",";
67         }
68         str+="};";
69         cr.outputline(str);
70         
71
72         cr.outputline("int typeobject::size(int type) {");
73         cr.outputline("return arsize[type];");
74         cr.outputline("}");
75
76         cr.outputline("int typeobject::sizeBytes(int type) {");
77         cr.outputline("return arsizeBytes[type];");
78         cr.outputline("}");
79
80         cr.outputline("int typeobject::numElements(int type, int fieldindex) {");
81         cr.outputline("return arnumelements[type][fieldindex];");
82         cr.outputline("}");
83         cr.outputline("typeobject::typeobject() {}");
84     }
85
86     private void generatecomputesize() {
87         int max=TypeDescriptor.counter;
88         cr.outputline("void typeobject::computesizes("+rg.name+"_state * obj) {");
89         cr.outputline("obj->computesizes(arsize,arnumelements);");
90         cr.outputline("for(int i=0;i<"+max+";i++) {");
91         cr.outputline("int bits=arsize[i];");
92         cr.outputline("int bytes=bits>>3;");
93         cr.outputline("if (bits%8) bytes++;");
94         cr.outputline("arsizeBytes[i]=bytes;");
95         cr.outputline("}");
96         cr.outputline("}");
97     }
98
99     private void generateheader() {
100         crhead.outputline("#include \""+rg.headername + "\"");
101         crhead.outputline("class typeobject {");
102         crhead.outputline("public:");
103         crhead.outputline("typeobject();");
104         crhead.outputline("int getfield(int type, int fieldindex);");
105         crhead.outputline("int isArray(int type, int fieldindex);");
106         crhead.outputline("int isPtr(int type, int fieldindex);");
107         crhead.outputline("int numElements(int type, int fieldindex);");
108         crhead.outputline("int size(int type);");
109         crhead.outputline("int sizeBytes(int type);");
110         crhead.outputline("int getnumfields(int type);");
111         crhead.outputline("bool issubtype(int subtype, int type);");
112         crhead.outputline("void computesizes("+rg.name+"_state *);");
113         crhead.outputline("};");
114     }
115
116     
117     private void generategetfield() {
118         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
119             TypeDescriptor ttd=(TypeDescriptor)it.next();
120             String str="";
121
122             if (ttd instanceof StructureTypeDescriptor) {
123                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
124                 str="int argetfield"+std.getId()+"["+std.fieldlist.size()+"]={";
125                 for(int i=0;i<std.fieldlist.size();i++) {
126                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
127                     TypeDescriptor td = fd.getType();
128                     str+=String.valueOf(td.getId());
129                     if ((i+1)!=std.fieldlist.size())
130                         str+=",";
131                 }
132                 str+="};";
133                 cr.outputline(str);
134             } else
135                 cr.outputline("int argetfield"+ttd.getId()+"[0];");
136         }
137         int max=TypeDescriptor.counter;
138         String str="int* argetfield["+String.valueOf(max)+"]={";
139         for(int i=0;i<max;i++) {
140             str+="argetfield"+i;
141             if (((i+1)!=max))
142                 str+=",";
143         }
144         str+="};";
145         cr.outputline(str);
146         
147         cr.outputline("int typeobject::getfield(int type, int fieldindex) {");
148         cr.outputline("return argetfield[type][fieldindex];");
149         cr.outputline("}");
150     }
151
152    private void generategetnumfields() {
153         int max=TypeDescriptor.counter;
154         String str="int argetnumfield["+String.valueOf(max)+"]={";
155         for(int i=0;i<max;i++) {
156             TypeDescriptor ttd=tdarray[i];
157             if (ttd instanceof StructureTypeDescriptor) {
158                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
159                 str+=String.valueOf(std.fieldlist.size());
160             } else
161                 str+="0";
162             if (((i+1)!=max))
163                 str+=",";
164         }
165         str+="};";
166         cr.outputline(str);
167         
168         cr.outputline("int typeobject::getnumfields(int type) {");
169         cr.outputline("return argetnumfield[type];");
170         cr.outputline("}");
171     }
172     private void generateisArray() {
173         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
174             TypeDescriptor ttd=(TypeDescriptor)it.next();
175             String str="";
176
177             if (ttd instanceof StructureTypeDescriptor) {
178                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
179                 str="int arisArray"+std.getId()+"["+std.fieldlist.size()+"]={";
180                 for(int i=0;i<std.fieldlist.size();i++) {
181                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
182                     TypeDescriptor td = fd.getType();
183                     if (fd instanceof ArrayDescriptor)
184                         str+="1";
185                     else
186                         str+="0";
187                     if ((i+1)!=std.fieldlist.size())
188                         str+=",";
189                 }
190                 str+="};";
191                 cr.outputline(str);
192             } else
193                 cr.outputline("int arisArray"+ttd.getId()+"[0];");
194         }
195         int max=TypeDescriptor.counter;
196         String str="int* arisArray["+String.valueOf(max)+"]={";
197         for(int i=0;i<max;i++) {
198             str+="arisArray"+i;
199             if (((i+1)!=max))
200                 str+=",";
201         }
202         str+="};";
203         cr.outputline(str);
204         
205         cr.outputline("int typeobject::isArray(int type, int fieldindex) {");
206         cr.outputline("return arisArray[type][fieldindex];");
207         cr.outputline("}");
208     }
209     private void generateisPtr() {
210         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
211             TypeDescriptor ttd=(TypeDescriptor)it.next();
212             String str="";
213
214             if (ttd instanceof StructureTypeDescriptor) {
215                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
216                 str="int arisPtr"+std.getId()+"["+std.fieldlist.size()+"]={";
217                 for(int i=0;i<std.fieldlist.size();i++) {
218                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
219                     if (fd.getPtr())
220                         str+="1";
221                     else
222                         str+="0";
223                     if ((i+1)!=std.fieldlist.size())
224                         str+=",";
225                 }
226                 str+="};";
227                 cr.outputline(str);
228             } else
229                 cr.outputline("int arisPtr"+ttd.getId()+"[0];");
230         }
231         int max=TypeDescriptor.counter;
232         String str="int* arisPtr["+String.valueOf(max)+"]={";
233         for(int i=0;i<max;i++) {
234             str+="arisPtr"+i;
235             if (((i+1)!=max))
236                 str+=",";
237         }
238         str+="};";
239         cr.outputline(str);
240         
241         cr.outputline("int typeobject::isPtr(int type, int fieldindex) {");
242         cr.outputline("return arisPtr[type][fieldindex];");
243         cr.outputline("}");
244     }
245
246     void generateissubtype() {
247         int max=TypeDescriptor.counter;
248         String str="bool arissubtype["+max+"]["+max+"]={";
249         for(int i=0;i<max;i++) {
250             str+="{";
251             for(int j=0;j<max;j++) {
252                 TypeDescriptor tdi=tdarray[i];
253                 TypeDescriptor tdj=tdarray[j];
254                 if (tdi.isSubtypeOf(tdj))
255                     str+="1";
256                 else
257                     str+="0";
258                 if ((j+1)!=max)
259                     str+=",";
260             }
261             str+="}";
262             if ((i+1)!=max)
263                 str+=",";
264         }
265         str+="};";
266         cr.outputline(str);
267         cr.outputline("bool typeobject::issubtype(int subtype, int type) {");
268         cr.outputline("return arissubtype[subtype][type];");
269         cr.outputline("}");
270     }
271 }