KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > typing > ConstraintCollectorBV


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-2000 Etienne Gagnon. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 package soot.jimple.toolkits.typing;
28
29 import soot.*;
30 import soot.jimple.*;
31 import soot.util.*;
32 import java.util.*;
33
34 class ConstraintCollectorBV extends AbstractStmtSwitch
35 {
36   private TypeResolverBV resolver;
37   private ClassHierarchy hierarchy;
38   private boolean uses; // if true, include use contraints
39

40   private JimpleBody stmtBody;
41
42   public ConstraintCollectorBV(TypeResolverBV resolver, boolean uses)
43   {
44     this.resolver = resolver;
45     this.uses = uses;
46
47     hierarchy = resolver.hierarchy();
48   }
49
50   public void collect(Stmt stmt, JimpleBody stmtBody)
51   {
52     this.stmtBody = stmtBody;
53     stmt.apply(this);
54   }
55   private void handleInvokeExpr(InvokeExpr ie)
56   {
57     if(!uses)
58       return;
59
60     if(ie instanceof InterfaceInvokeExpr)
61       {
62     InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie;
63     
64     SootMethodRef method = invoke.getMethodRef();
65     Value base = invoke.getBase();
66     
67     if(base instanceof Local)
68       {
69         Local local = (Local) base;
70         
71         TypeVariableBV localType = resolver.typeVariable(local);
72         
73         localType.addParent(resolver.typeVariable(method.declaringClass()));
74       }
75     
76     int count = invoke.getArgCount();
77     
78     for(int i = 0; i < count; i++)
79       {
80         if(invoke.getArg(i) instanceof Local)
81           {
82         Local local = (Local) invoke.getArg(i);
83
84         TypeVariableBV localType = resolver.typeVariable(local);
85
86         localType.addParent(resolver.typeVariable(method.parameterType(i)));
87           }
88       }
89       }
90     else if(ie instanceof SpecialInvokeExpr)
91       {
92     SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie;
93
94     SootMethodRef method = invoke.getMethodRef();
95     Value base = invoke.getBase();
96
97     if(base instanceof Local)
98       {
99         Local local = (Local) base;
100
101         TypeVariableBV localType = resolver.typeVariable(local);
102
103         localType.addParent(resolver.typeVariable(method.declaringClass()));
104       }
105
106     int count = invoke.getArgCount();
107
108     for(int i = 0; i < count; i++)
109       {
110         if(invoke.getArg(i) instanceof Local)
111           {
112         Local local = (Local) invoke.getArg(i);
113
114         TypeVariableBV localType = resolver.typeVariable(local);
115
116         localType.addParent(resolver.typeVariable(method.parameterType(i)));
117           }
118       }
119       }
120     else if(ie instanceof VirtualInvokeExpr)
121       {
122     VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie;
123
124     SootMethodRef method = invoke.getMethodRef();
125     Value base = invoke.getBase();
126
127     if(base instanceof Local)
128       {
129         Local local = (Local) base;
130
131         TypeVariableBV localType = resolver.typeVariable(local);
132
133         localType.addParent(resolver.typeVariable(method.declaringClass()));
134       }
135
136     int count = invoke.getArgCount();
137
138     for(int i = 0; i < count; i++)
139       {
140         if(invoke.getArg(i) instanceof Local)
141           {
142         Local local = (Local) invoke.getArg(i);
143
144         TypeVariableBV localType = resolver.typeVariable(local);
145
146         localType.addParent(resolver.typeVariable(method.parameterType(i)));
147           }
148       }
149       }
150     else if(ie instanceof StaticInvokeExpr)
151       {
152     StaticInvokeExpr invoke = (StaticInvokeExpr) ie;
153
154     SootMethodRef method = invoke.getMethodRef();
155
156     int count = invoke.getArgCount();
157
158     for(int i = 0; i < count; i++)
159       {
160         if(invoke.getArg(i) instanceof Local)
161           {
162         Local local = (Local) invoke.getArg(i);
163
164         TypeVariableBV localType = resolver.typeVariable(local);
165
166         localType.addParent(resolver.typeVariable(method.parameterType(i)));
167           }
168       }
169       }
170     else
171       {
172     throw new RuntimeException JavaDoc("Unhandled invoke expression type: " + ie.getClass());
173       }
174   }
175
176   public void caseBreakpointStmt(BreakpointStmt stmt)
177   {
178     // Do nothing
179
}
180
181   public void caseInvokeStmt(InvokeStmt stmt)
182   {
183     handleInvokeExpr((InvokeExpr) stmt.getInvokeExpr());
184   }
185
186   public void caseAssignStmt(AssignStmt stmt)
187   {
188     Value l = stmt.getLeftOp();
189     Value r = stmt.getRightOp();
190
191     TypeVariableBV left = null;
192     TypeVariableBV right = null;
193
194     //******** LEFT ********
195

196     if(l instanceof ArrayRef)
197       {
198     ArrayRef ref = (ArrayRef) l;
199     Value base = ref.getBase();
200     Value index = ref.getIndex();
201     
202     TypeVariableBV baseType = resolver.typeVariable((Local) base);
203     baseType.makeElement();
204     left = baseType.element();
205     
206     if(index instanceof Local)
207       {
208         if(uses)
209           {
210         resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
211           }
212       }
213       }
214     else if(l instanceof Local)
215       {
216     left = resolver.typeVariable((Local) l);
217       }
218     else if(l instanceof InstanceFieldRef)
219       {
220     InstanceFieldRef ref = (InstanceFieldRef) l;
221     
222     if(uses)
223       {
224         TypeVariableBV baseType = resolver.typeVariable((Local) ref.getBase());
225         baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
226        
227         left = resolver.typeVariable(ref.getField().getType());
228       }
229       }
230     else if(l instanceof StaticFieldRef)
231       {
232     if(uses)
233       {
234         StaticFieldRef ref = (StaticFieldRef) l;
235         
236         left = resolver.typeVariable(ref.getField().getType());
237       }
238       }
239     else
240       {
241     throw new RuntimeException JavaDoc("Unhandled assignment left hand side type: " + l.getClass());
242       }
243
244     //******** RIGHT ********
245

246     if(r instanceof ArrayRef)
247       {
248     ArrayRef ref = (ArrayRef) r;
249     Value base = ref.getBase();
250     Value index = ref.getIndex();
251     
252     TypeVariableBV baseType = resolver.typeVariable((Local) base);
253     baseType.makeElement();
254     right = baseType.element();
255     
256     if(index instanceof Local)
257       {
258         if(uses)
259           {
260         resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
261           }
262       }
263       }
264     else if(r instanceof DoubleConstant)
265       {
266     right = resolver.typeVariable(DoubleType.v());
267       }
268     else if(r instanceof FloatConstant)
269       {
270     right = resolver.typeVariable(FloatType.v());
271       }
272     else if(r instanceof IntConstant)
273       {
274     right = resolver.typeVariable(IntType.v());
275       }
276     else if(r instanceof LongConstant)
277       {
278     right = resolver.typeVariable(LongType.v());
279       }
280     else if(r instanceof NullConstant)
281       {
282     right = resolver.typeVariable(NullType.v());
283       }
284     else if(r instanceof StringConstant)
285       {
286     right = resolver.typeVariable(RefType.v("java.lang.String"));
287       }
288     else if(r instanceof ClassConstant)
289       {
290     right = resolver.typeVariable(RefType.v("java.lang.Class"));
291       }
292     else if(r instanceof BinopExpr)
293       {
294     //******** BINOP EXPR ********
295

296     BinopExpr be = (BinopExpr) r;
297
298     Value lv = be.getOp1();
299     Value rv = be.getOp2();
300     
301     TypeVariableBV lop;
302     TypeVariableBV rop;
303
304     //******** LEFT ********
305
if(lv instanceof Local)
306       {
307         lop = resolver.typeVariable((Local) lv);
308       }
309     else if(lv instanceof DoubleConstant)
310       {
311         lop = resolver.typeVariable(DoubleType.v());
312       }
313     else if(lv instanceof FloatConstant)
314       {
315         lop = resolver.typeVariable(FloatType.v());
316       }
317     else if(lv instanceof IntConstant)
318       {
319         lop = resolver.typeVariable(IntType.v());
320       }
321     else if(lv instanceof LongConstant)
322       {
323         lop = resolver.typeVariable(LongType.v());
324       }
325     else if(lv instanceof NullConstant)
326       {
327         lop = resolver.typeVariable(NullType.v());
328       }
329     else if(lv instanceof StringConstant)
330       {
331         lop = resolver.typeVariable(RefType.v("java.lang.String"));
332       }
333     else if(lv instanceof ClassConstant)
334       {
335         lop = resolver.typeVariable(RefType.v("java.lang.Class"));
336       }
337     else
338       {
339         throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
340       }
341     
342     //******** RIGHT ********
343
if(rv instanceof Local)
344       {
345         rop = resolver.typeVariable((Local) rv);
346       }
347     else if(rv instanceof DoubleConstant)
348       {
349         rop = resolver.typeVariable(DoubleType.v());
350       }
351     else if(rv instanceof FloatConstant)
352       {
353         rop = resolver.typeVariable(FloatType.v());
354       }
355     else if(rv instanceof IntConstant)
356       {
357         rop = resolver.typeVariable(IntType.v());
358       }
359     else if(rv instanceof LongConstant)
360       {
361         rop = resolver.typeVariable(LongType.v());
362       }
363     else if(rv instanceof NullConstant)
364       {
365         rop = resolver.typeVariable(NullType.v());
366       }
367     else if(rv instanceof StringConstant)
368       {
369         rop = resolver.typeVariable(RefType.v("java.lang.String"));
370       }
371     else if(rv instanceof ClassConstant)
372       {
373         rop = resolver.typeVariable(RefType.v("java.lang.Class"));
374       }
375     else
376       {
377         throw new RuntimeException JavaDoc("Unhandled binary expression right operand type: " + rv.getClass());
378       }
379     
380     if((be instanceof AddExpr) ||
381        (be instanceof SubExpr) ||
382        (be instanceof MulExpr) ||
383        (be instanceof DivExpr) ||
384        (be instanceof RemExpr) ||
385        (be instanceof AndExpr) ||
386        (be instanceof OrExpr) ||
387        (be instanceof XorExpr))
388       {
389         if(uses)
390           {
391         TypeVariableBV common = resolver.typeVariable();
392         rop.addParent(common);
393         lop.addParent(common);
394           }
395         
396         if(left != null)
397           {
398         rop.addParent(left);
399         lop.addParent(left);
400           }
401       }
402     else if((be instanceof ShlExpr) ||
403         (be instanceof ShrExpr) ||
404         (be instanceof UshrExpr))
405       {
406         if(uses)
407           {
408         rop.addParent(resolver.typeVariable(IntType.v()));
409           }
410         
411         right = lop;
412       }
413     else if((be instanceof CmpExpr) ||
414         (be instanceof CmpgExpr) ||
415         (be instanceof CmplExpr) ||
416         (be instanceof EqExpr) ||
417         (be instanceof GeExpr) ||
418         (be instanceof GtExpr) ||
419         (be instanceof LeExpr) ||
420         (be instanceof LtExpr) ||
421         (be instanceof NeExpr))
422       {
423         if(uses)
424           {
425         TypeVariableBV common = resolver.typeVariable();
426         rop.addParent(common);
427         lop.addParent(common);
428           }
429         
430         right = resolver.typeVariable(IntType.v());
431       }
432     else
433       {
434         throw new RuntimeException JavaDoc("Unhandled binary expression type: " + be.getClass());
435       }
436       }
437     else if(r instanceof CastExpr)
438       {
439     CastExpr ce = (CastExpr) r;
440
441     right = resolver.typeVariable(ce.getCastType());
442       }
443     else if(r instanceof InstanceOfExpr)
444       {
445     InstanceOfExpr ioe = (InstanceOfExpr) r;
446     
447     right = resolver.typeVariable(IntType.v());
448       }
449     else if(r instanceof InvokeExpr)
450       {
451     InvokeExpr ie = (InvokeExpr) r;
452
453     handleInvokeExpr(ie);
454
455     right = resolver.typeVariable(ie.getMethodRef().returnType());
456       }
457     else if(r instanceof NewArrayExpr)
458       {
459     NewArrayExpr nae = (NewArrayExpr) r;
460
461     Type baseType = nae.getBaseType();
462
463     if(baseType instanceof ArrayType)
464       {
465         right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType,
466                               ((ArrayType) baseType).numDimensions + 1));
467       }
468     else
469       {
470         right = resolver.typeVariable(ArrayType.v(baseType, 1));
471       }
472
473     if(uses)
474       {
475         Value size = nae.getSize();
476         if(size instanceof Local)
477           {
478         TypeVariableBV var = resolver.typeVariable((Local) size);
479         var.addParent(resolver.typeVariable(IntType.v()));
480           }
481       }
482       }
483     else if(r instanceof NewExpr)
484       {
485     NewExpr na = (NewExpr) r;
486
487     right = resolver.typeVariable(na.getBaseType());
488       }
489     else if(r instanceof NewMultiArrayExpr)
490       {
491     NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
492
493     right = resolver.typeVariable(nmae.getBaseType());
494
495     if(uses)
496       {
497         for(int i = 0; i < nmae.getSizeCount(); i++)
498           {
499         Value size = nmae.getSize(i);
500         if(size instanceof Local)
501           {
502             TypeVariableBV var = resolver.typeVariable((Local) size);
503             var.addParent(resolver.typeVariable(IntType.v()));
504           }
505           }
506       }
507       }
508     else if(r instanceof LengthExpr)
509       {
510     LengthExpr le = (LengthExpr) r;
511
512     if(uses)
513       {
514         if(le.getOp() instanceof Local)
515           {
516         resolver.typeVariable((Local) le.getOp()).makeElement();
517           }
518       }
519
520     right = resolver.typeVariable(IntType.v());
521       }
522     else if(r instanceof NegExpr)
523       {
524     NegExpr ne = (NegExpr) r;
525
526     if(ne.getOp() instanceof Local)
527       {
528         right = resolver.typeVariable((Local) ne.getOp());
529       }
530     else if(ne.getOp() instanceof DoubleConstant)
531       {
532         right = resolver.typeVariable(DoubleType.v());
533       }
534     else if(ne.getOp() instanceof FloatConstant)
535       {
536         right = resolver.typeVariable(FloatType.v());
537       }
538     else if(ne.getOp() instanceof IntConstant)
539       {
540         right = resolver.typeVariable(IntType.v());
541       }
542     else if(ne.getOp() instanceof LongConstant)
543       {
544         right = resolver.typeVariable(LongType.v());
545       }
546     else
547       {
548         throw new RuntimeException JavaDoc("Unhandled neg expression operand type: " + ne.getOp().getClass());
549       }
550       }
551     else if(r instanceof Local)
552       {
553     right = resolver.typeVariable((Local) r);
554       }
555     else if(r instanceof InstanceFieldRef)
556       {
557     InstanceFieldRef ref = (InstanceFieldRef) r;
558
559     if(uses)
560       {
561         TypeVariableBV baseType = resolver.typeVariable((Local) ref.getBase());
562         baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
563       }
564     
565     right = resolver.typeVariable(ref.getField().getType());
566       }
567     else if(r instanceof StaticFieldRef)
568       {
569     StaticFieldRef ref = (StaticFieldRef) r;
570
571     right = resolver.typeVariable(ref.getField().getType());
572       }
573     else
574       {
575     throw new RuntimeException JavaDoc("Unhandled assignment right hand side type: " + r.getClass());
576       }
577
578     if(left != null && right != null)
579       {
580     right.addParent(left);
581       }
582   }
583
584   public void caseIdentityStmt(IdentityStmt stmt)
585   {
586     Value l = stmt.getLeftOp();
587     Value r = stmt.getRightOp();
588
589     if(l instanceof Local)
590       {
591     TypeVariableBV left = resolver.typeVariable((Local) l);
592
593     if(!(r instanceof CaughtExceptionRef))
594       {
595         TypeVariableBV right = resolver.typeVariable(r.getType());
596         right.addParent(left);
597       }
598     else
599       {
600         List exceptionTypes = TrapManager.getExceptionTypesOf(stmt, stmtBody);
601         Iterator typeIt = exceptionTypes.iterator();
602
603         while(typeIt.hasNext())
604           {
605         Type t = (Type) typeIt.next();
606
607         resolver.typeVariable(t).addParent(left);
608           }
609
610         if(uses)
611           {
612         left.addParent(resolver.typeVariable(RefType.v("java.lang.Throwable")));
613           }
614       }
615       }
616   }
617
618   public void caseEnterMonitorStmt(EnterMonitorStmt stmt)
619   {
620     if(uses)
621       {
622     if(stmt.getOp() instanceof Local)
623       {
624         TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp());
625         
626         op.addParent(resolver.typeVariable(RefType.v("java.lang.Object")));
627       }
628       }
629   }
630
631   public void caseExitMonitorStmt(ExitMonitorStmt stmt)
632   {
633     if(uses)
634       {
635     if(stmt.getOp() instanceof Local)
636       {
637         TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp());
638         
639         op.addParent(resolver.typeVariable(RefType.v("java.lang.Object")));
640       }
641       }
642   }
643
644   public void caseGotoStmt(GotoStmt stmt)
645   {
646   }
647
648   public void caseIfStmt(IfStmt stmt)
649   {
650     if(uses)
651       {
652     ConditionExpr cond = (ConditionExpr) stmt.getCondition();
653     
654     BinopExpr expr = (BinopExpr) cond;
655     Value lv = expr.getOp1();
656     Value rv = expr.getOp2();
657     
658     TypeVariableBV lop;
659     TypeVariableBV rop;
660
661     //******** LEFT ********
662
if(lv instanceof Local)
663       {
664         lop = resolver.typeVariable((Local) lv);
665       }
666     else if(lv instanceof DoubleConstant)
667       {
668         lop = resolver.typeVariable(DoubleType.v());
669       }
670     else if(lv instanceof FloatConstant)
671       {
672         lop = resolver.typeVariable(FloatType.v());
673       }
674     else if(lv instanceof IntConstant)
675       {
676         lop = resolver.typeVariable(IntType.v());
677       }
678     else if(lv instanceof LongConstant)
679       {
680         lop = resolver.typeVariable(LongType.v());
681       }
682     else if(lv instanceof NullConstant)
683       {
684         lop = resolver.typeVariable(NullType.v());
685       }
686     else if(lv instanceof StringConstant)
687       {
688         lop = resolver.typeVariable(RefType.v("java.lang.String"));
689       }
690     else if(lv instanceof ClassConstant)
691       {
692         lop = resolver.typeVariable(RefType.v("java.lang.Class"));
693       }
694     else
695       {
696         throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
697       }
698     
699     //******** RIGHT ********
700
if(rv instanceof Local)
701       {
702         rop = resolver.typeVariable((Local) rv);
703       }
704     else if(rv instanceof DoubleConstant)
705       {
706         rop = resolver.typeVariable(DoubleType.v());
707       }
708     else if(rv instanceof FloatConstant)
709       {
710         rop = resolver.typeVariable(FloatType.v());
711       }
712     else if(rv instanceof IntConstant)
713       {
714         rop = resolver.typeVariable(IntType.v());
715       }
716     else if(rv instanceof LongConstant)
717       {
718         rop = resolver.typeVariable(LongType.v());
719       }
720     else if(rv instanceof NullConstant)
721       {
722         rop = resolver.typeVariable(NullType.v());
723       }
724     else if(rv instanceof StringConstant)
725       {
726         rop = resolver.typeVariable(RefType.v("java.lang.String"));
727       }
728     else if(rv instanceof ClassConstant)
729       {
730         rop = resolver.typeVariable(RefType.v("java.lang.Class"));
731       }
732     else
733       {
734         throw new RuntimeException JavaDoc("Unhandled binary expression right operand type: " + rv.getClass());
735       }
736
737     TypeVariableBV common = resolver.typeVariable();
738     rop.addParent(common);
739     lop.addParent(common);
740       }
741   }
742
743   public void caseLookupSwitchStmt(LookupSwitchStmt stmt)
744   {
745     if(uses)
746       {
747     Value key = stmt.getKey();
748
749     if(key instanceof Local)
750       {
751         resolver.typeVariable((Local) key).addParent(resolver.typeVariable(IntType.v()));
752       }
753       }
754   }
755
756   public void caseNopStmt(NopStmt stmt)
757   {
758   }
759
760   public void caseReturnStmt(ReturnStmt stmt)
761   {
762     if(uses)
763       {
764     if(stmt.getOp() instanceof Local)
765       {
766         resolver.typeVariable((Local) stmt.getOp()).
767           addParent(resolver.typeVariable(stmtBody.getMethod().getReturnType()));
768       }
769       }
770   }
771
772   public void caseReturnVoidStmt(ReturnVoidStmt stmt)
773   {
774   }
775
776   public void caseTableSwitchStmt(TableSwitchStmt stmt)
777   {
778     if(uses)
779       {
780     Value key = stmt.getKey();
781     
782     if(key instanceof Local)
783       {
784         resolver.typeVariable((Local) key).addParent(resolver.typeVariable(IntType.v()));
785       }
786       }
787   }
788
789   public void caseThrowStmt(ThrowStmt stmt)
790   {
791     if(uses)
792       {
793     if(stmt.getOp() instanceof Local)
794       {
795         TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp());
796         
797         op.addParent(resolver.typeVariable(RefType.v("java.lang.Throwable")));
798       }
799       }
800   }
801
802   public void defaultCase(Stmt stmt)
803   {
804     throw new RuntimeException JavaDoc("Unhandled statement type: " + stmt.getClass());
805   }
806 }
807
Popular Tags