2 bug fixes to getRequiredConstraints
[repair.git] / Repair / RepairCompiler / MCC / IR / UpdateNode.java
1 package MCC.IR;
2 import java.util.*;
3 import MCC.State;
4
5 class UpdateNode {
6     Vector updates;
7     Vector bindings;
8     Vector invariants;
9     Hashtable binding;
10     Rule rule;
11
12     public UpdateNode(Rule r) {
13         updates=new Vector();
14         bindings=new Vector();
15         invariants=new Vector();
16         binding=new Hashtable();
17         rule=r;
18     }
19
20     public Rule getRule() {
21         return rule;
22     }
23
24     public String toString() {
25         String st="";
26         st+="Bindings:\n";
27         for(int i=0;i<bindings.size();i++)
28             st+=bindings.get(i).toString()+"\n";
29         st+="---------------------\n";
30         st+="Updates:\n";
31         for(int i=0;i<updates.size();i++)
32             st+=updates.get(i).toString()+"\n";
33         st+="---------------------\n";
34         st+="Invariants:\n";
35         for(int i=0;i<invariants.size();i++)
36             st+=((Expr)invariants.get(i)).name()+"\n";
37         st+="---------------------\n";
38         return st;
39     }
40
41     public void addBindings(Vector v) {
42         for (int i=0;i<v.size();i++) {
43             addBinding((Binding)v.get(i));
44         }
45     }
46
47     public boolean checkupdates() {
48         if (!checkconflicts()) /* Do we have conflicting concrete updates */
49             return false;
50         if (computeordering()) /* Ordering exists */
51             return true;
52         return false;
53     }
54
55     private boolean computeordering() {
56         /* Build dependency graph between updates */
57         HashSet graph=new HashSet();
58         Hashtable mapping=new Hashtable();
59         for(int i=0;i<updates.size();i++) {
60             Updates u=(Updates)updates.get(i);
61             GraphNode gn=new GraphNode(String.valueOf(i),u);
62             mapping.put(u, gn);
63             graph.add(gn);
64         }
65         for(int i=0;i<updates.size();i++) {
66             Updates u1=(Updates)updates.get(i);
67             if (u1.isAbstract())
68                 continue;
69             for(int j=0;j<updates.size();j++) {
70                 Updates u2=(Updates)updates.get(j);
71                 if (!u2.isExpr())
72                     continue;
73                 Descriptor d=u1.getDescriptor();
74                 Expr subexpr=null;
75                 Expr intindex=null;
76
77                 if (u2.isField()) {
78                     subexpr=((DotExpr)u2.getLeftExpr()).getExpr();
79                     intindex=((DotExpr)u2.getLeftExpr()).getIndex();
80                 }
81                 if (u2.getRightExpr().usesDescriptor(d)||
82                     (subexpr!=null&&subexpr.usesDescriptor(d))||
83                     (intindex!=null&&intindex.usesDescriptor(d))) {
84                     /* Add edge for dependency */
85                     GraphNode gn1=(GraphNode) mapping.get(u1);
86                     GraphNode gn2=(GraphNode) mapping.get(u2);
87                     GraphNode.Edge e=new GraphNode.Edge("dependency",gn2);
88                     gn1.addEdge(e);
89                 }
90             }
91         }
92
93         if (!GraphNode.DFS.depthFirstSearch(graph))  /* DFS & check for acyclicity */
94             return false;
95
96         TreeSet topologicalsort = new TreeSet(new Comparator() {
97                 public boolean equals(Object obj) { return false; }
98                 public int compare(Object o1, Object o2) {
99                     GraphNode g1 = (GraphNode) o1;
100                     GraphNode g2 = (GraphNode) o2;
101                     return g2.getFinishingTime() - g1.getFinishingTime();
102                 }
103             });
104         topologicalsort.addAll(graph);
105         Vector sortedvector=new Vector();
106         for(Iterator sort=topologicalsort.iterator();sort.hasNext();) {
107             GraphNode gn=(GraphNode)sort.next();
108             sortedvector.add(gn.getOwner());
109         }
110         updates=sortedvector; //replace updates with the sorted array
111         return true;
112     }
113
114     private boolean checkconflicts() {
115         Set toremove=new HashSet();
116         for(int i=0;i<updates.size();i++) {
117             Updates u1=(Updates)updates.get(i);
118             if (!u1.isAbstract()) {
119                 Descriptor d=u1.getDescriptor();
120                 for(int j=0;j<invariants.size();j++) {
121                     Expr invariant=(Expr)invariants.get(j);
122                     if (invariant.usesDescriptor(d))
123                         return false;
124                 }
125             }
126             for(int j=0;j<updates.size();j++) {
127                 Updates u2=(Updates)updates.get(j);
128                 if (i==j)
129                     continue;
130                 if (u1.isAbstract()||u2.isAbstract())
131                     continue;  /* Abstract updates are already accounted for by graph */
132                 if (u1.getDescriptor()!=u2.getDescriptor())
133                     continue; /* No interference - different descriptors */
134
135                 if ((u1.getOpcode()==Opcode.GT||u1.getOpcode()==Opcode.GE)&&
136                     (u2.getOpcode()==Opcode.GT||u2.getOpcode()==Opcode.GE))
137                     continue; /* Can be satisfied simultaneously */
138
139                 if ((u1.getOpcode()==Opcode.LT||u1.getOpcode()==Opcode.LE)&&
140                     (u2.getOpcode()==Opcode.LT||u2.getOpcode()==Opcode.LE))
141                     continue;
142                 if ((u1.getOpcode()==u2.getOpcode())&&
143                     u1.isExpr()&&u2.isExpr()&&
144                     u1.getRightExpr().equals(null, u2.getRightExpr())) {
145                     /*We'll remove the second occurence*/
146                     if (i>j)
147                         toremove.add(u1);
148                     else
149                         toremove.add(u2);
150                     continue;
151                 }
152
153                 /* Handle = or != NULL */
154                 if ((((u1.getOpcode()==Opcode.EQ)&&(u2.getOpcode()==Opcode.NE))||
155                      ((u1.getOpcode()==Opcode.NE)&&(u2.getOpcode()==Opcode.EQ)))&&
156                     (((u1.isExpr()&&u1.getRightExpr().isNull())&&(!u2.isExpr()||u2.getRightExpr().isNonNull()))
157                      ||((!u1.isExpr()||u1.getRightExpr().isNonNull())&&(u2.isExpr()&&u2.getRightExpr().isNull())))) {
158                     if (u1.getOpcode()==Opcode.NE)
159                         toremove.add(u1);
160                     else
161                         toremove.add(u2);
162                     continue;
163                 }
164
165                 /* Handle = and != to different constants */
166                 if ((((u1.getOpcode()==Opcode.EQ)&&(u2.getOpcode()==Opcode.NE))||
167                     ((u1.getOpcode()==Opcode.NE)&&(u2.getOpcode()==Opcode.EQ)))&&
168                     (u1.isExpr()&&u1.getRightExpr() instanceof LiteralExpr)&&
169                     (u2.isExpr()&&u2.getRightExpr() instanceof LiteralExpr)&&
170                     !u1.getRightExpr().equals(u2.getRightExpr())) {
171                     if (u1.getOpcode()==Opcode.NE)
172                         toremove.add(u1);
173                     else
174                         toremove.add(u2);
175                     continue;
176                 }
177
178                 /* Compatible operations < & <= */
179                 if (((u1.getOpcode()==Opcode.LT)||(u1.getOpcode()==Opcode.LE))&&
180                     ((u2.getOpcode()==Opcode.LT)||(u2.getOpcode()==Opcode.LE)))
181                     continue;
182
183                 /* Compatible operations > & >= */
184                 if (((u1.getOpcode()==Opcode.GT)||(u1.getOpcode()==Opcode.GE))&&
185                     ((u2.getOpcode()==Opcode.GT)||(u2.getOpcode()==Opcode.GE)))
186                     continue;
187                 /* Ranges */
188
189                 //XXXXXX: TODO
190                 /* Equality & Comparisons */
191                 //XXXXXX: TODO
192
193                 return false; /* They interfere */
194             }
195         }
196         updates.removeAll(toremove);
197         return true;
198     }
199
200     public void addBinding(Binding b) {
201         bindings.add(b);
202         binding.put(b.getVar(),b);
203     }
204
205     public int numBindings() {
206         return bindings.size();
207     }
208
209     public Binding getBinding(int i) {
210         return (Binding)bindings.get(i);
211     }
212
213     public Binding getBinding(VarDescriptor vd) {
214         if (binding.containsKey(vd))
215             return (Binding)binding.get(vd);
216         else
217             return null;
218     }
219
220     public void addInvariant(Expr e) {
221         invariants.add(e);
222     }
223
224     public int numInvariants() {
225         return invariants.size();
226     }
227
228     public Expr getInvariant(int i) {
229         return (Expr)invariants.get(i);
230     }
231
232     public void addUpdate(Updates u) {
233         updates.add(u);
234     }
235
236     public int numUpdates() {
237         return updates.size();
238     }
239     public Updates getUpdate(int i) {
240         return (Updates)updates.get(i);
241     }
242
243     private MultUpdateNode getMultUpdateNode(boolean negate, Descriptor d, RepairGenerator rg) {
244         Termination termination=rg.termination;
245         MultUpdateNode mun=null;
246         GraphNode gn;
247         if (negate)
248             gn=(GraphNode)termination.abstractremove.get(d);
249         else
250             gn=(GraphNode)termination.abstractadd.get(d);
251         TermNode tn=(TermNode)gn.getOwner();
252         for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
253             GraphNode gn2=((GraphNode.Edge) edgeit.next()).getTarget();
254             if (!rg.removed.contains(gn2)) {
255                 TermNode tn2=(TermNode)gn2.getOwner();
256                 if (tn2.getType()==TermNode.UPDATE) {
257                     mun=tn2.getUpdate();
258                     break;
259                 }
260             }
261         }
262         if (mun==null)
263             throw new Error("Can't find update node!");
264         return mun;
265     }
266
267     public void generate_abstract(CodeWriter cr, Updates u, RepairGenerator rg) {
268         State state=rg.state;
269         Expr abstractexpr=u.getLeftExpr();
270         boolean negated=u.negate;
271         Descriptor d=null;
272         Expr left=null;
273         Expr right=null;
274         boolean istuple=false;
275         if (abstractexpr instanceof TupleOfExpr) {
276             TupleOfExpr toe=(TupleOfExpr) abstractexpr;
277             d=toe.relation;
278             left=toe.left;
279             right=toe.right;
280             istuple=true;
281         } else if (abstractexpr instanceof ElementOfExpr) {
282             ElementOfExpr eoe=(ElementOfExpr) abstractexpr;
283             d=eoe.set;
284             left=eoe.element;
285             istuple=false;
286         } else {
287             throw new Error("Unsupported Expr");
288         }
289         MultUpdateNode mun=getMultUpdateNode(negated,d,rg);
290         VarDescriptor leftvar=VarDescriptor.makeNew("leftvar");
291         VarDescriptor rightvar=VarDescriptor.makeNew("rightvar");
292         left.generate(cr, leftvar);
293         if (istuple)
294             right.generate(cr,rightvar);
295
296         if (negated) {
297             if (istuple) {
298                 RelationDescriptor rd=(RelationDescriptor)d;
299                 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
300                 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
301                 if (usageimage)
302                     cr.outputline("SimpleHashremove("+rg.stmodel+"->"+rd.getJustSafeSymbol()+"_hash, (int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
303                 if (usageinvimage)
304                     cr.outputline("SimpleHashremove("+rg.stmodel+"->"+rd.getJustSafeSymbol()+"_hashinv, (int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
305
306                 for(int i=0;i<state.vRules.size();i++) {
307                     Rule r=(Rule)state.vRules.get(i);
308                     if (r.getInclusion().getTargetDescriptors().contains(rd)) {
309                         for(int j=0;j<mun.numUpdates();j++) {
310                             UpdateNode un=mun.getUpdate(i);
311                             if (un.getRule()==r) {
312                                 /* Update for rule rule r */
313                                 String name=(String)rg.updatenames.get(un);
314                                 cr.outputline("RepairHashaddrelation("+rg.strepairtable+","+rd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
315                             }
316                         }
317                     }
318                 }
319             } else {
320                 SetDescriptor sd=(SetDescriptor) d;
321                 cr.outputline("SimpleHashremove("+rg.stmodel+"->"+sd.getJustSafeSymbol()+"_hash, (int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
322
323                 for(int i=0;i<state.vRules.size();i++) {
324                     Rule r=(Rule)state.vRules.get(i);
325                     if (r.getInclusion().getTargetDescriptors().contains(sd)) {
326                         for(int j=0;j<mun.numUpdates();j++) {
327                             UpdateNode un=mun.getUpdate(j);
328                             if (un.getRule()==r) {
329                                 /* Update for rule rule r */
330                                 String name=(String)rg.updatenames.get(un);
331                                 cr.outputline("RepairHashaddset("+rg.strepairtable+","+sd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
332                             }
333                         }
334                     }
335                 }
336             }
337         } else {
338             /* Generate update */
339             if (istuple) {
340                 RelationDescriptor rd=(RelationDescriptor) d;
341                 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
342                 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
343                 if (usageimage)
344                     cr.outputline("SimpleHashadd("+rg.stmodel+"->"+rd.getJustSafeSymbol()+"_hash, (int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
345                 if (usageinvimage)
346                     cr.outputline("SimpleHashadd("+rg.stmodel+"->"+rd.getJustSafeSymbol()+"_hashinv, (int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
347
348                 UpdateNode un=mun.getUpdate(0);
349                 String name=(String)rg.updatenames.get(un);
350                 cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
351             } else {
352                 SetDescriptor sd=(SetDescriptor)d;
353                 cr.outputline("SimpleHashadd("+rg.stmodel+"->"+sd.getJustSafeSymbol()+"_hash, (int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
354
355                 UpdateNode un=mun.getUpdate(0);
356                 /* Update for rule rule r */
357                 String name=(String)rg.updatenames.get(un);
358                 cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+");");
359             }
360         }
361     }
362
363     public void generate(CodeWriter cr, boolean removal, boolean modify, String slot0, String slot1, String slot2, RepairGenerator rg) {
364         if (!removal&&!modify)
365             generate_bindings(cr, slot0,slot1);
366         for(int i=0;i<updates.size();i++) {
367             Updates u=(Updates)updates.get(i);
368             VarDescriptor right=VarDescriptor.makeNew("right");
369             if (u.getType()==Updates.ABSTRACT) {
370                 generate_abstract(cr, u, rg);
371                 return;
372             }
373
374             switch(u.getType()) {
375             case Updates.EXPR:
376                 u.getRightExpr().generate(cr,right);
377                 break;
378             case Updates.POSITION:
379             case Updates.ACCESSPATH:
380                 if (u.getRightPos()==0) {
381                     cr.addDeclaration("int", right.getSafeSymbol());
382                     cr.outputline(right.getSafeSymbol()+"="+slot0+";");
383                 } else if (u.getRightPos()==1) {
384                     cr.addDeclaration("int", right.getSafeSymbol());
385                     cr.outputline(right.getSafeSymbol()+"="+slot1+";");
386                 } else if (u.getRightPos()==2) {
387                     cr.addDeclaration("int", right.getSafeSymbol());
388                     cr.outputline(right.getSafeSymbol()+"="+slot2+";");
389                 } else throw new Error("Error w/ Position");
390                 break;
391             default:
392                 throw new Error();
393             }
394
395             if (u.getType()==Updates.ACCESSPATH) {
396                 VarDescriptor newright=VarDescriptor.makeNew("right");
397                 generate_accesspath(cr, right,newright,u);
398                 right=newright;
399             }
400             VarDescriptor left=VarDescriptor.makeNew("left");
401             u.getLeftExpr().generate(cr,left);
402             Opcode op=u.getOpcode();
403             cr.outputline("if (!("+left.getSafeSymbol()+op+right.getSafeSymbol()+"))");
404             cr.startblock();
405
406             if (op==Opcode.GT)
407                 cr.outputline(right.getSafeSymbol()+"++;");
408             else if (op==Opcode.GE)
409                 ;
410             else if (op==Opcode.EQ)
411                 ;
412             else if (op==Opcode.NE)
413                 cr.outputline(right.getSafeSymbol()+"++;");
414             else if (op==Opcode.LT)
415                 cr.outputline(right.getSafeSymbol()+"--;");
416             else if (op==Opcode.LE)
417                 ;
418             else throw new Error();
419             if (u.isGlobal()) {
420                 VarDescriptor vd=((VarExpr)u.getLeftExpr()).getVar();
421                 cr.outputline(vd.getSafeSymbol()+"="+right.getSafeSymbol()+";");
422             } else if (u.isField()) {
423                 /* NEED TO FIX */
424                 Expr subexpr=((DotExpr)u.getLeftExpr()).getExpr();
425                 Expr intindex=((DotExpr)u.getLeftExpr()).getIndex();
426                 VarDescriptor subvd=VarDescriptor.makeNew("subexpr");
427                 VarDescriptor indexvd=VarDescriptor.makeNew("index");
428                 subexpr.generate(cr,subvd);
429                 if (intindex!=null)
430                     intindex.generate(cr,indexvd);
431                 FieldDescriptor fd=(FieldDescriptor)u.getDescriptor();
432                 StructureTypeDescriptor std=(StructureTypeDescriptor)subexpr.getType();
433                 Expr offsetbits = std.getOffsetExpr(fd);
434                 if (fd instanceof ArrayDescriptor) {
435                     fd = ((ArrayDescriptor) fd).getField();
436                 }
437
438                 if (intindex != null) {
439                     Expr basesize = fd.getBaseSizeExpr();
440                     offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
441                 }
442                 Expr offsetbytes = new OpExpr(Opcode.SHR, offsetbits,new IntegerLiteralExpr(3));
443                 Expr byteaddress=new OpExpr(Opcode.ADD, offsetbytes, subexpr);
444                 VarDescriptor addr=VarDescriptor.makeNew("byteaddress");
445                 byteaddress.generate(cr,addr);
446
447                 if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
448                     ReservedTypeDescriptor rtd=(ReservedTypeDescriptor)fd.getType();
449                     if (rtd==ReservedTypeDescriptor.INT) {
450                         cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
451                     } else if (rtd==ReservedTypeDescriptor.SHORT) {
452                         cr.outputline("*((short *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
453                     } else if (rtd==ReservedTypeDescriptor.BYTE) {
454                         cr.outputline("*((char *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
455                     } else if (rtd==ReservedTypeDescriptor.BIT) {
456                         Expr tmp = new OpExpr(Opcode.SHL, offsetbytes, new IntegerLiteralExpr(3));
457                         Expr offset=new OpExpr(Opcode.SUB, offsetbits, tmp);
458                         Expr mask=new OpExpr(Opcode.SHL, new IntegerLiteralExpr(1), offset);
459                         VarDescriptor maskvar=VarDescriptor.makeNew("mask");
460                         mask.generate(cr,maskvar);
461                         cr.outputline("*((char *) "+addr.getSafeSymbol()+")|="+maskvar.getSafeSymbol()+";");
462                         cr.outputline("if (!"+right.getSafeSymbol()+")");
463                         cr.outputline("*((char *) "+addr.getSafeSymbol()+")^="+maskvar.getSafeSymbol()+";");
464                     } else throw new Error();
465                 } else {
466                     /* Pointer */
467                     cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
468                 }
469             }
470             cr.endblock();
471         }
472     }
473
474
475     private void generate_accesspath(CodeWriter cr, VarDescriptor right, VarDescriptor newright, Updates u) {
476         Vector dotvector=new Vector();
477         Expr ptr=u.getRightExpr();
478         VarExpr rightve=new VarExpr(right);
479         right.td=ReservedTypeDescriptor.INT;
480
481         while(true) {
482             /* Does something other than a dereference? */
483             dotvector.add(ptr);
484             if (ptr instanceof DotExpr)
485                 ptr=((DotExpr)ptr).left;
486             else if (ptr instanceof CastExpr)
487                 ptr=((CastExpr)ptr).getExpr();
488             if (ptr instanceof VarExpr) {
489                 /* Finished constructing vector */
490                 break;
491             }
492         }
493         ArrayAnalysis.AccessPath ap=u.getAccessPath();
494         VarDescriptor init=VarDescriptor.makeNew("init");
495         if (ap.isSet()) {
496             cr.addDeclaration("int", init.getSafeSymbol());
497             cr.outputline(init.getSafeSymbol()+"= SimpleHashfirstkey("+ap.getSet().getSafeSymbol()+"_hash);");
498             init.td=ap.getSet().getType();
499         } else {
500             init=ap.getVar();
501         }
502         Expr newexpr=new VarExpr(init);
503         int apindex=0;
504         for(int i=dotvector.size()-1;i>=0;i--) {
505             Expr e=(Expr)dotvector.get(i);
506             if (e instanceof CastExpr) {
507                 newexpr.td=e.td;
508                 newexpr=new CastExpr(((CastExpr)e).getType(),newexpr);
509             } else if (e instanceof DotExpr) {
510                 DotExpr de=(DotExpr)e;
511                 if (de.getField() instanceof ArrayDescriptor) {
512                     DotExpr de2=new DotExpr(newexpr,de.field,new IntegerLiteralExpr(0));
513                     de2.fd=de.fd;
514                     de2.fieldtype=de.fieldtype;
515                     de2.td=de.td;
516                     OpExpr offset=new OpExpr(Opcode.SUB,rightve,de2);
517                     OpExpr index=new OpExpr(Opcode.DIV,offset,de.fieldtype.getSizeExpr());
518                     if (u.getRightPos()==apindex) {
519                         index.generate(cr,newright);
520                         return;
521                     } else {
522                         DotExpr de3=new DotExpr(newexpr,de.field,index);
523                         de3.fd=de.fd;
524                         de3.td=de.td;
525                         de3.fieldtype=de.fieldtype;
526                         newexpr=de3;
527                     }
528                 } else {
529                     DotExpr de2=new DotExpr(newexpr,de.field,null);
530                     de2.fd=de.fd;
531                     de2.fieldtype=de.fieldtype;
532                     de2.td=de.td;
533                     newexpr=de2;
534                 }
535                 apindex++;
536             } else throw new Error();
537         }
538         throw new Error();
539     }
540
541     private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
542         for(int i=0;i<bindings.size();i++) {
543             Binding b=(Binding)bindings.get(i);
544
545             if (b.getType()==Binding.SEARCH) {
546                 VarDescriptor vd=b.getVar();
547                 cr.addDeclaration(vd.getType().getGenerateType().getSafeSymbol(), vd.getSafeSymbol());
548                 cr.outputline(vd.getSafeSymbol()+"=SimpleHashfirstkey("+b.getSet().getSafeSymbol()+"_hash);");
549             } else if (b.getType()==Binding.CREATE) {
550                 throw new Error("Creation not supported");
551                 //              source.generateSourceAlloc(cr,vd,b.getSet());
552             } else {
553                 VarDescriptor vd=b.getVar();
554                 switch(b.getPosition()) {
555                 case 0:
556                     cr.addDeclaration(vd.getType().getGenerateType().getSafeSymbol(), vd.getSafeSymbol());
557                     cr.outputline(vd.getSafeSymbol()+"="+slot0+";");
558                     break;
559                 case 1:
560                     cr.addDeclaration(vd.getType().getGenerateType().getSafeSymbol(), vd.getSafeSymbol());
561                     cr.outputline(vd.getSafeSymbol()+"="+slot1+";");
562                     break;
563                 default:
564                     throw new Error("Slot >1 doesn't exist.");
565                 }
566             }
567         }
568     }
569 }