Source Code Cross Referenced for Body.java in  » Code-Analyzer » soot » soot » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » soot » soot 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Soot - a J*va Optimization Framework
002:         * Copyright (C) 1997-1999 Raja Vallee-Rai
003:         *
004:         * This library is free software; you can redistribute it and/or
005:         * modify it under the terms of the GNU Lesser General Public
006:         * License as published by the Free Software Foundation; either
007:         * version 2.1 of the License, or (at your option) any later version.
008:         *
009:         * This library is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012:         * Lesser General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU Lesser General Public
015:         * License along with this library; if not, write to the
016:         * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017:         * Boston, MA 02111-1307, USA.
018:         */
019:
020:        /*
021:         * Modified by the Sable Research Group and others 1997-1999.
022:         * See the 'credits' file distributed with Soot for the complete list of
023:         * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
024:         */
025:
026:        package soot;
027:
028:        import java.io.ByteArrayOutputStream;
029:        import java.io.OutputStreamWriter;
030:        import java.io.PrintWriter;
031:        import java.io.Serializable;
032:        import java.util.ArrayList;
033:        import java.util.HashMap;
034:        import java.util.Iterator;
035:        import java.util.List;
036:        import java.util.Map;
037:
038:        import soot.jimple.CaughtExceptionRef;
039:        import soot.jimple.DefinitionStmt;
040:        import soot.jimple.IdentityStmt;
041:        import soot.jimple.InstanceInvokeExpr;
042:        import soot.jimple.InvokeExpr;
043:        import soot.jimple.InvokeStmt;
044:        import soot.jimple.ParameterRef;
045:        import soot.jimple.ThisRef;
046:        import soot.options.Options;
047:        import soot.tagkit.AbstractHost;
048:        import soot.tagkit.CodeAttribute;
049:        import soot.tagkit.Tag;
050:        import soot.toolkits.exceptions.PedanticThrowAnalysis;
051:        import soot.toolkits.graph.ExceptionalUnitGraph;
052:        import soot.toolkits.graph.UnitGraph;
053:        import soot.toolkits.scalar.FlowSet;
054:        import soot.toolkits.scalar.InitAnalysis;
055:        import soot.toolkits.scalar.LocalDefs;
056:        import soot.toolkits.scalar.SimpleLiveLocals;
057:        import soot.toolkits.scalar.SmartLocalDefs;
058:        import soot.util.Chain;
059:        import soot.util.EscapedWriter;
060:        import soot.util.HashChain;
061:
062:        /**
063:         *   Abstract base class that models the body (code attribute) of a Java method.
064:         *   Classes that implement an Intermediate Representation for a method body should subclass it.
065:         *   In particular the classes GrimpBody, JimpleBody and BafBody all extend this
066:         *   class. This class provides methods that are common to any IR, such as methods
067:         *   to get the body's units (statements), traps, and locals.
068:         *
069:         *  @see soot.grimp.GrimpBody
070:         *  @see soot.jimple.JimpleBody
071:         *  @see soot.baf.BafBody
072:         */
073:        public abstract class Body extends AbstractHost implements  Serializable {
074:            /** The method associated with this Body. */
075:            protected transient SootMethod method = null;
076:
077:            /** The chain of locals for this Body. */
078:            protected Chain<Local> localChain = new HashChain<Local>();
079:
080:            /** The chain of traps for this Body. */
081:            protected Chain<Trap> trapChain = new HashChain<Trap>();
082:
083:            /** The chain of units for this Body. */
084:            protected PatchingChain<Unit> unitChain = new PatchingChain<Unit>(
085:                    new HashChain<Unit>());
086:
087:            /** Creates a deep copy of this Body. */
088:            abstract public Object clone();
089:
090:            /** Creates a Body associated to the given method.  Used by subclasses during initialization.
091:             *  Creation of a Body is triggered by e.g. Jimple.v().newBody(options).
092:             */
093:            protected Body(SootMethod m) {
094:                this .method = m;
095:            }
096:
097:            /** Creates an extremely empty Body.  The Body is not associated to any method. */
098:            protected Body() {
099:            }
100:
101:            /**
102:             * Returns the method associated with this Body.
103:             * @return the method that owns this body.
104:             */
105:            public SootMethod getMethod() {
106:                if (method == null)
107:                    throw new RuntimeException("no method associated w/ body");
108:                return method;
109:            }
110:
111:            /**
112:             * Sets the method associated with this Body.
113:             * @param method the method that owns this body.
114:             *
115:             */
116:            public void setMethod(SootMethod method) {
117:                this .method = method;
118:            }
119:
120:            /** Returns the number of locals declared in this body. */
121:            public int getLocalCount() {
122:                return localChain.size();
123:            }
124:
125:            /** Copies the contents of the given Body into this one. */
126:            public Map<Object, Object> importBodyContentsFrom(Body b) {
127:                HashMap<Object, Object> bindings = new HashMap<Object, Object>();
128:
129:                {
130:                    Iterator<Unit> it = b.getUnits().iterator();
131:
132:                    // Clone units in body's statement list
133:                    while (it.hasNext()) {
134:                        Unit original = it.next();
135:                        Unit copy = (Unit) original.clone();
136:
137:                        copy.addAllTagsOf(original);
138:
139:                        // Add cloned unit to our unitChain.
140:                        unitChain.addLast(copy);
141:
142:                        // Build old <-> new map to be able to patch up references to other units
143:                        // within the cloned units. (these are still refering to the original
144:                        // unit objects).
145:                        bindings.put(original, copy);
146:                    }
147:                }
148:
149:                {
150:                    // Clone trap units.
151:                    Iterator<Trap> it = b.getTraps().iterator();
152:                    while (it.hasNext()) {
153:                        Trap original = it.next();
154:                        Trap copy = (Trap) original.clone();
155:
156:                        // Add cloned unit to our trap list.
157:                        trapChain.addLast(copy);
158:
159:                        // Store old <-> new mapping.
160:                        bindings.put(original, copy);
161:                    }
162:                }
163:
164:                {
165:                    // Clone local units.
166:                    Iterator<Local> it = b.getLocals().iterator();
167:                    while (it.hasNext()) {
168:                        Local original = it.next();
169:                        Local copy = (Local) original.clone();
170:
171:                        // Add cloned unit to our trap list.
172:                        localChain.addLast(copy);
173:
174:                        // Build old <-> new mapping.
175:                        bindings.put(original, copy);
176:                    }
177:                }
178:
179:                {
180:                    // Patch up references within units using our (old <-> new) map.
181:                    Iterator<UnitBox> it = getAllUnitBoxes().iterator();
182:                    while (it.hasNext()) {
183:                        UnitBox box = it.next();
184:                        Unit newObject, oldObject = box.getUnit();
185:
186:                        // if we have a reference to an old object, replace it
187:                        // it's clone.
188:                        if ((newObject = (Unit) bindings.get(oldObject)) != null)
189:                            box.setUnit(newObject);
190:
191:                    }
192:                }
193:
194:                {
195:                    // backpatching all local variables.
196:                    Iterator<ValueBox> it = getUseBoxes().iterator();
197:                    while (it.hasNext()) {
198:                        ValueBox vb = it.next();
199:                        if (vb.getValue() instanceof  Local)
200:                            vb.setValue((Value) bindings.get(vb.getValue()));
201:                    }
202:                    it = getDefBoxes().iterator();
203:                    while (it.hasNext()) {
204:                        ValueBox vb = it.next();
205:                        if (vb.getValue() instanceof  Local)
206:                            vb.setValue((Value) bindings.get(vb.getValue()));
207:                    }
208:                }
209:                return bindings;
210:            }
211:
212:            /** Verifies a few sanity conditions on the contents on this body. */
213:            public void validate() {
214:                //System.out.println("body: "+this.getUnits());
215:                validateLocals();
216:                validateTraps();
217:                validateUnitBoxes();
218:                if (Options.v().debug() || Options.v().validate()) {
219:                    validateUses();
220:                    validateValueBoxes();
221:                    checkInit();
222:                    checkTypes();
223:                    checkLocals();
224:                }
225:            }
226:
227:            /** Verifies that a ValueBox is not used in more than one place. */
228:            public void validateValueBoxes() {
229:                List<ValueBox> l = getUseAndDefBoxes();
230:                for (int i = 0; i < l.size(); i++) {
231:                    for (int j = 0; j < l.size(); j++) {
232:                        if (i == j)
233:                            continue;
234:                        if (l.get(i) == l.get(j)) {
235:                            System.err.println("Aliased value box : "
236:                                    + l.get(i) + " in " + getMethod());
237:                            for (Iterator<Unit> uIt = getUnits().iterator(); uIt
238:                                    .hasNext();) {
239:                                final Unit u = uIt.next();
240:                                System.err.println("" + u);
241:                            }
242:                            throw new RuntimeException("Aliased value box : "
243:                                    + l.get(i) + " in " + getMethod());
244:                        }
245:                    }
246:                }
247:            }
248:
249:            /** Verifies that each Local of getUseAndDefBoxes() is in this body's locals Chain. */
250:            public void validateLocals() {
251:                Iterator<ValueBox> it = getUseBoxes().iterator();
252:                while (it.hasNext()) {
253:                    validateLocal(it.next());
254:                }
255:                it = getDefBoxes().iterator();
256:                while (it.hasNext()) {
257:                    validateLocal(it.next());
258:                }
259:            }
260:
261:            private void validateLocal(ValueBox vb) {
262:                Value value;
263:                if ((value = vb.getValue()) instanceof  Local) {
264:                    //System.out.println("localChain: "+localChain);
265:                    if (!localChain.contains(value))
266:                        throw new RuntimeException("Local not in chain : "
267:                                + value + " in " + getMethod());
268:                }
269:            }
270:
271:            /** Verifies that the begin, end and handler units of each trap are in this body. */
272:            public void validateTraps() {
273:                Iterator<Trap> it = getTraps().iterator();
274:                while (it.hasNext()) {
275:                    Trap t = it.next();
276:                    if (!unitChain.contains(t.getBeginUnit()))
277:                        throw new RuntimeException("begin not in chain"
278:                                + " in " + getMethod());
279:
280:                    if (!unitChain.contains(t.getEndUnit()))
281:                        throw new RuntimeException("end not in chain" + " in "
282:                                + getMethod());
283:
284:                    if (!unitChain.contains(t.getHandlerUnit()))
285:                        throw new RuntimeException("handler not in chain"
286:                                + " in " + getMethod());
287:                }
288:            }
289:
290:            /** Verifies that the UnitBoxes of this Body all point to a Unit contained within this body. */
291:            public void validateUnitBoxes() {
292:                Iterator<UnitBox> it = getAllUnitBoxes().iterator();
293:                while (it.hasNext()) {
294:                    UnitBox ub = it.next();
295:                    if (!unitChain.contains(ub.getUnit()))
296:                        throw new RuntimeException(
297:                                "Unitbox points outside unitChain! to unit : "
298:                                        + ub.getUnit() + " in " + getMethod());
299:                }
300:            }
301:
302:            /** Verifies that each use in this Body has a def. */
303:            public void validateUses() {
304:                UnitGraph g = new ExceptionalUnitGraph(this );
305:                LocalDefs ld = new SmartLocalDefs(g, new SimpleLiveLocals(g));
306:
307:                Iterator<Unit> unitsIt = getUnits().iterator();
308:                while (unitsIt.hasNext()) {
309:                    Unit u = unitsIt.next();
310:                    Iterator<ValueBox> useBoxIt = u.getUseBoxes().iterator();
311:                    while (useBoxIt.hasNext()) {
312:                        Value v = (useBoxIt.next()).getValue();
313:                        if (v instanceof  Local) {
314:                            // This throws an exception if there is
315:                            // no def already; we check anyhow.
316:                            List<Unit> l = ld.getDefsOfAt((Local) v, u);
317:                            if (l.size() == 0) {
318:                                for (Iterator<Unit> uuIt = getUnits()
319:                                        .iterator(); uuIt.hasNext();) {
320:                                    final Unit uu = uuIt.next();
321:                                    System.err.println("" + uu);
322:                                }
323:                                throw new RuntimeException(
324:                                        "no defs for value: " + v + "!"
325:                                                + " in " + getMethod());
326:                            }
327:                        }
328:                    }
329:                }
330:            }
331:
332:            /** Returns a backed chain of the locals declared in this Body. */
333:            public Chain<Local> getLocals() {
334:                return localChain;
335:            }
336:
337:            /** Returns a backed view of the traps found in this Body. */
338:            public Chain<Trap> getTraps() {
339:                return trapChain;
340:            }
341:
342:            /** Return LHS of the first identity stmt assigning from \@this. **/
343:            public Local getThisLocal() {
344:                Iterator<Unit> unitsIt = getUnits().iterator();
345:
346:                while (unitsIt.hasNext()) {
347:                    Unit s = unitsIt.next();
348:                    if (s instanceof  IdentityStmt
349:                            && ((IdentityStmt) s).getRightOp() instanceof  ThisRef)
350:                        return (Local) (((IdentityStmt) s).getLeftOp());
351:                }
352:
353:                throw new RuntimeException("couldn't find identityref!"
354:                        + " in " + getMethod());
355:            }
356:
357:            /** Return LHS of the first identity stmt assigning from \@parameter i. **/
358:            public Local getParameterLocal(int i) {
359:                Iterator<Unit> unitsIt = getUnits().iterator();
360:                while (unitsIt.hasNext()) {
361:                    Unit s = unitsIt.next();
362:                    if (s instanceof  IdentityStmt
363:                            && ((IdentityStmt) s).getRightOp() instanceof  ParameterRef) {
364:                        IdentityStmt is = (IdentityStmt) s;
365:                        ParameterRef pr = (ParameterRef) is.getRightOp();
366:                        if (pr.getIndex() == i)
367:                            return (Local) is.getLeftOp();
368:                    }
369:                }
370:
371:                throw new RuntimeException("couldn't find parameterref!"
372:                        + " in " + getMethod());
373:            }
374:
375:            /**
376:             *  Returns the Chain of Units that make up this body. The units are
377:             *  returned as a PatchingChain. The client can then manipulate the chain,
378:             *  adding and removing units, and the changes will be reflected in the body.
379:             *  Since a PatchingChain is returned the client need <i>not</i> worry about removing exception
380:             *  boundary units or otherwise corrupting the chain.
381:             *
382:             *  @return the units in this Body
383:             *
384:             *  @see PatchingChain
385:             *  @see Unit
386:             */
387:            public PatchingChain<Unit> getUnits() {
388:                return unitChain;
389:            }
390:
391:            /**
392:             * Returns the result of iterating through all Units in this body
393:             * and querying them for their UnitBoxes.  All UnitBoxes thus
394:             * found are returned.  Branching Units and statements which use
395:             * PhiExpr will have UnitBoxes; a UnitBox contains a Unit that is
396:             * either a target of a branch or is being used as a pointer to
397:             * the end of a CFG block.
398:             *
399:             * <p> This method is typically used for pointer patching, eg when
400:             * the unit chain is cloned.
401:             *
402:             * @return A list of all the UnitBoxes held by this body's units.
403:             * @see UnitBox
404:             * @see #getUnitBoxes(boolean)
405:             * @see Unit#getUnitBoxes()
406:             * @see soot.shimple.PhiExpr#getUnitBoxes()
407:             **/
408:            public List<UnitBox> getAllUnitBoxes() {
409:                ArrayList<UnitBox> unitBoxList = new ArrayList<UnitBox>();
410:                {
411:                    Iterator<Unit> it = unitChain.iterator();
412:                    while (it.hasNext()) {
413:                        Unit item = it.next();
414:                        unitBoxList.addAll(item.getUnitBoxes());
415:                    }
416:                }
417:
418:                {
419:                    Iterator<Trap> it = trapChain.iterator();
420:                    while (it.hasNext()) {
421:                        Trap item = it.next();
422:                        unitBoxList.addAll(item.getUnitBoxes());
423:                    }
424:                }
425:
426:                {
427:                    Iterator<Tag> it = getTags().iterator();
428:                    while (it.hasNext()) {
429:                        Tag t = it.next();
430:                        if (t instanceof  CodeAttribute)
431:                            unitBoxList.addAll(((CodeAttribute) t)
432:                                    .getUnitBoxes());
433:                    }
434:                }
435:
436:                return unitBoxList;
437:            }
438:
439:            /**
440:             * If branchTarget is true, returns the result of iterating
441:             * through all branching Units in this body and querying them for
442:             * their UnitBoxes. These UnitBoxes contain Units that are the
443:             * target of a branch.  This is useful for, say, labeling blocks
444:             * or updating the targets of branching statements.
445:             *
446:             * <p> If branchTarget is false, returns the result of iterating
447:             * through the non-branching Units in this body and querying them
448:             * for their UnitBoxes.  Any such UnitBoxes (typically from
449:             * PhiExpr) contain a Unit that indicates the end of a CFG block.
450:             *
451:             * @return a list of all the UnitBoxes held by this body's
452:             * branching units.
453:             *
454:             * @see UnitBox
455:             * @see #getAllUnitBoxes()
456:             * @see Unit#getUnitBoxes()
457:             * @see soot.shimple.PhiExpr#getUnitBoxes()
458:             **/
459:            public List<UnitBox> getUnitBoxes(boolean branchTarget) {
460:                ArrayList<UnitBox> unitBoxList = new ArrayList<UnitBox>();
461:                {
462:                    Iterator<Unit> it = unitChain.iterator();
463:                    while (it.hasNext()) {
464:                        Unit item = it.next();
465:                        if (branchTarget) {
466:                            if (item.branches())
467:                                unitBoxList.addAll(item.getUnitBoxes());
468:                        } else {
469:                            if (!item.branches())
470:                                unitBoxList.addAll(item.getUnitBoxes());
471:                        }
472:                    }
473:                }
474:
475:                {
476:                    Iterator<Trap> it = trapChain.iterator();
477:                    while (it.hasNext()) {
478:                        Trap item = it.next();
479:                        unitBoxList.addAll(item.getUnitBoxes());
480:                    }
481:                }
482:
483:                {
484:                    Iterator<Tag> it = getTags().iterator();
485:                    while (it.hasNext()) {
486:                        Tag t = it.next();
487:                        if (t instanceof  CodeAttribute)
488:                            unitBoxList.addAll(((CodeAttribute) t)
489:                                    .getUnitBoxes());
490:                    }
491:                }
492:
493:                return unitBoxList;
494:            }
495:
496:            /**
497:             *   Returns the result of iterating through all Units in this
498:             *   body and querying them for ValueBoxes used.
499:             *   All of the ValueBoxes found are then returned as a List.
500:             *
501:             *   @return a list of all the ValueBoxes for the Values used this body's units.
502:             *
503:             *   @see Value
504:             *   @see Unit#getUseBoxes
505:             *   @see ValueBox
506:             *   @see Value
507:             *
508:             */
509:            public List<ValueBox> getUseBoxes() {
510:                ArrayList<ValueBox> useBoxList = new ArrayList<ValueBox>();
511:
512:                Iterator<Unit> it = unitChain.iterator();
513:                while (it.hasNext()) {
514:                    Unit item = it.next();
515:                    useBoxList.addAll(item.getUseBoxes());
516:                }
517:                return useBoxList;
518:            }
519:
520:            /**
521:             *   Returns the result of iterating through all Units in this
522:             *   body and querying them for ValueBoxes defined.
523:             *   All of the ValueBoxes found are then returned as a List.
524:             *
525:             *   @return a list of all the ValueBoxes for Values defined by this body's units.
526:             *
527:             *   @see Value
528:             *   @see Unit#getDefBoxes
529:             *   @see ValueBox
530:             *   @see Value
531:             */
532:            public List<ValueBox> getDefBoxes() {
533:                ArrayList<ValueBox> defBoxList = new ArrayList<ValueBox>();
534:
535:                Iterator<Unit> it = unitChain.iterator();
536:                while (it.hasNext()) {
537:                    Unit item = it.next();
538:                    defBoxList.addAll(item.getDefBoxes());
539:                }
540:                return defBoxList;
541:            }
542:
543:            /**
544:             *   Returns a list of boxes corresponding to Values
545:             * either used or defined in any unit of this Body.
546:             *
547:             *   @return a list of ValueBoxes for held by the body's Units.
548:             *
549:             *   @see Value
550:             *   @see Unit#getUseAndDefBoxes
551:             *   @see ValueBox
552:             *   @see Value
553:             */
554:            public List<ValueBox> getUseAndDefBoxes() {
555:                ArrayList<ValueBox> useAndDefBoxList = new ArrayList<ValueBox>();
556:
557:                Iterator<Unit> it = unitChain.iterator();
558:                while (it.hasNext()) {
559:                    Unit item = it.next();
560:                    useAndDefBoxList.addAll(item.getUseBoxes());
561:                    useAndDefBoxList.addAll(item.getDefBoxes());
562:                }
563:                return useAndDefBoxList;
564:            }
565:
566:            private void checkLocals() {
567:                Chain<Local> locals = getLocals();
568:
569:                Iterator<Local> it = locals.iterator();
570:                while (it.hasNext()) {
571:                    Local l = it.next();
572:                    if (l.getType() instanceof  VoidType)
573:                        throw new RuntimeException("Local " + l + " in "
574:                                + method + " defined with void type");
575:                }
576:            }
577:
578:            private void checkTypes() {
579:                Chain<Unit> units = getUnits();
580:
581:                Iterator<Unit> it = units.iterator();
582:                while (it.hasNext()) {
583:                    Unit stmt = (it.next());
584:                    InvokeExpr iexpr = null;
585:
586:                    String errorSuffix = " at " + stmt + " in " + getMethod();
587:
588:                    if (stmt instanceof  DefinitionStmt) {
589:                        DefinitionStmt astmt = (DefinitionStmt) stmt;
590:                        if (!(astmt.getRightOp() instanceof  CaughtExceptionRef)) {
591:                            Type leftType = Type.toMachineType(astmt
592:                                    .getLeftOp().getType());
593:                            Type rightType = Type.toMachineType(astmt
594:                                    .getRightOp().getType());
595:
596:                            checkCopy(leftType, rightType, errorSuffix);
597:                            if (astmt.getRightOp() instanceof  InvokeExpr)
598:                                iexpr = (InvokeExpr) (astmt.getRightOp());
599:                        }
600:                    }
601:
602:                    if (stmt instanceof  InvokeStmt)
603:                        iexpr = ((InvokeStmt) stmt).getInvokeExpr();
604:
605:                    if (iexpr != null) {
606:                        SootMethodRef called = iexpr.getMethodRef();
607:
608:                        if (iexpr instanceof  InstanceInvokeExpr) {
609:                            InstanceInvokeExpr iiexpr = (InstanceInvokeExpr) iexpr;
610:                            checkCopy(called.declaringClass().getType(), iiexpr
611:                                    .getBase().getType(),
612:                                    " in receiver of call" + errorSuffix);
613:                        }
614:
615:                        if (called.parameterTypes().size() != iexpr
616:                                .getArgCount())
617:                            throw new RuntimeException(
618:                                    "Warning: Argument count doesn't match up with signature in call"
619:                                            + errorSuffix + " in "
620:                                            + getMethod());
621:                        else
622:                            for (int i = 0; i < iexpr.getArgCount(); i++)
623:                                checkCopy(Type.toMachineType(called
624:                                        .parameterType(i)), Type
625:                                        .toMachineType(iexpr.getArg(i)
626:                                                .getType()), " in argument "
627:                                        + i + " of call" + errorSuffix);
628:                    }
629:                }
630:            }
631:
632:            private void checkCopy(Type leftType, Type rightType,
633:                    String errorSuffix) {
634:                if (leftType instanceof  PrimType
635:                        || rightType instanceof  PrimType) {
636:                    if (leftType instanceof  IntType
637:                            && rightType instanceof  IntType)
638:                        return;
639:                    if (leftType instanceof  LongType
640:                            && rightType instanceof  LongType)
641:                        return;
642:                    if (leftType instanceof  FloatType
643:                            && rightType instanceof  FloatType)
644:                        return;
645:                    if (leftType instanceof  DoubleType
646:                            && rightType instanceof  DoubleType)
647:                        return;
648:                    throw new RuntimeException(
649:                            "Warning: Bad use of primitive type" + errorSuffix
650:                                    + " in " + getMethod());
651:                }
652:
653:                if (rightType instanceof  NullType)
654:                    return;
655:                if (leftType instanceof  RefType
656:                        && ((RefType) leftType).getClassName().equals(
657:                                "java.lang.Object"))
658:                    return;
659:
660:                if (leftType instanceof  ArrayType
661:                        || rightType instanceof  ArrayType) {
662:                    if (leftType instanceof  ArrayType
663:                            && rightType instanceof  ArrayType)
664:                        return;
665:
666:                    throw new RuntimeException("Warning: Bad use of array type"
667:                            + errorSuffix + " in " + getMethod());
668:                }
669:
670:                if (leftType instanceof  RefType && rightType instanceof  RefType) {
671:                    SootClass leftClass = ((RefType) leftType).getSootClass();
672:                    SootClass rightClass = ((RefType) rightType).getSootClass();
673:
674:                    if (leftClass.isInterface()) {
675:                        if (rightClass.isInterface()) {
676:                            if (!(leftClass.getName().equals(
677:                                    rightClass.getName()) || Scene.v()
678:                                    .getActiveHierarchy()
679:                                    .isInterfaceSubinterfaceOf(rightClass,
680:                                            leftClass)))
681:                                throw new RuntimeException(
682:                                        "Warning: Bad use of interface type"
683:                                                + errorSuffix + " in "
684:                                                + getMethod());
685:                        } else {
686:                            // No quick way to check this for now.
687:                        }
688:                    } else {
689:                        if (rightClass.isInterface()) {
690:                            throw new RuntimeException(
691:                                    "Warning: trying to use interface type where non-Object class expected"
692:                                            + errorSuffix + " in "
693:                                            + getMethod());
694:                        } else {
695:                            if (!Scene.v().getActiveHierarchy()
696:                                    .isClassSubclassOfIncluding(rightClass,
697:                                            leftClass))
698:                                throw new RuntimeException(
699:                                        "Warning: Bad use of class type"
700:                                                + errorSuffix + " in "
701:                                                + getMethod());
702:                        }
703:                    }
704:                    return;
705:                }
706:                throw new RuntimeException("Warning: Bad types" + errorSuffix
707:                        + " in " + getMethod());
708:            }
709:
710:            @SuppressWarnings("unchecked")
711:            public void checkInit() {
712:                Chain<Unit> units = getUnits();
713:                ExceptionalUnitGraph g = new ExceptionalUnitGraph(this ,
714:                        PedanticThrowAnalysis.v(), false);
715:
716:                // FIXME: Work around for bug in soot
717:                Scene.v().releaseActiveHierarchy();
718:
719:                InitAnalysis analysis = new InitAnalysis(g);
720:                Iterator<Unit> it = units.iterator();
721:                while (it.hasNext()) {
722:                    Unit s = (it.next());
723:                    FlowSet init = (FlowSet) analysis.getFlowBefore(s);
724:                    List<ValueBox> uses = s.getUseBoxes();
725:                    Iterator<ValueBox> usesIt = uses.iterator();
726:                    while (usesIt.hasNext()) {
727:                        Value v = ((usesIt.next())).getValue();
728:                        if (v instanceof  Local) {
729:                            Local l = (Local) v;
730:                            if (!init.contains(l))
731:                                throw new RuntimeException(
732:                                        "Warning: Local variable " + l
733:                                                + " not definitely defined at "
734:                                                + s + " in " + method);
735:                        }
736:                    }
737:                }
738:            }
739:
740:            /**
741:             * {@inheritDoc}
742:             */
743:            @Override
744:            public String toString() {
745:                ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
746:                PrintWriter writerOut = new PrintWriter(new EscapedWriter(
747:                        new OutputStreamWriter(streamOut)));
748:                try {
749:                    Printer.v().printTo(this , writerOut);
750:                } catch (RuntimeException e) {
751:                    e.printStackTrace(writerOut);
752:                }
753:                writerOut.flush();
754:                writerOut.close();
755:                return streamOut.toString();
756:            }
757:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.