001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2004 Ondrej Lhotak
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Library General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 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: * Library General Public License for more details.
013: *
014: * You should have received a copy of the GNU Library 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: package soot.jimple.toolkits.callgraph;
021:
022: import soot.*;
023: import soot.jimple.*;
024: import java.util.*;
025:
026: public class UnreachableMethodTransformer extends BodyTransformer {
027: protected void internalTransform(Body b, String phaseName,
028: Map options) {
029: //System.out.println( "Performing UnreachableMethodTransformer" );
030: ReachableMethods reachableMethods = Scene.v()
031: .getReachableMethods();
032: SootMethod method = b.getMethod();
033: //System.out.println( "Method: " + method.getName() );
034: if (reachableMethods.contains(method))
035: return;
036:
037: JimpleBody body = (JimpleBody) method.getActiveBody();
038:
039: PatchingChain units = body.getUnits();
040: List<Unit> list = new Vector<Unit>();
041:
042: Local tmpRef = Jimple.v().newLocal("tmpRef",
043: RefType.v("java.io.PrintStream"));
044: body.getLocals().add(tmpRef);
045: list
046: .add(Jimple
047: .v()
048: .newAssignStmt(
049: tmpRef,
050: Jimple
051: .v()
052: .newStaticFieldRef(
053: Scene
054: .v()
055: .getField(
056: "<java.lang.System: java.io.PrintStream out>")
057: .makeRef())));
058:
059: SootMethod toCall = Scene.v().getMethod(
060: "<java.lang.Thread: void dumpStack()>");
061: list.add(Jimple.v().newInvokeStmt(
062: Jimple.v().newStaticInvokeExpr(toCall.makeRef())));
063:
064: toCall = Scene
065: .v()
066: .getMethod(
067: "<java.io.PrintStream: void println(java.lang.String)>");
068: list
069: .add(Jimple
070: .v()
071: .newInvokeStmt(
072: Jimple
073: .v()
074: .newVirtualInvokeExpr(
075: tmpRef,
076: toCall.makeRef(),
077: StringConstant
078: .v("Executing supposedly unreachable method:"))));
079: list.add(Jimple.v().newInvokeStmt(
080: Jimple.v().newVirtualInvokeExpr(
081: tmpRef,
082: toCall.makeRef(),
083: StringConstant.v("\t"
084: + method.getDeclaringClass().getName()
085: + "." + method.getName()))));
086:
087: toCall = Scene.v().getMethod(
088: "<java.lang.System: void exit(int)>");
089: list.add(Jimple.v().newInvokeStmt(
090: Jimple.v().newStaticInvokeExpr(toCall.makeRef(),
091: IntConstant.v(1))));
092:
093: /*
094: Stmt r;
095: if( method.getReturnType() instanceof VoidType ) {
096: list.add( r=Jimple.v().newReturnVoidStmt() );
097: } else if( method.getReturnType() instanceof RefLikeType ) {
098: list.add( r=Jimple.v().newReturnStmt( NullConstant.v() ) );
099: } else if( method.getReturnType() instanceof PrimType ) {
100: if( method.getReturnType() instanceof DoubleType ) {
101: list.add( r=Jimple.v().newReturnStmt( DoubleConstant.v( 0 ) ) );
102: } else if( method.getReturnType() instanceof LongType ) {
103: list.add( r=Jimple.v().newReturnStmt( LongConstant.v( 0 ) ) );
104: } else if( method.getReturnType() instanceof FloatType ) {
105: list.add( r=Jimple.v().newReturnStmt( FloatConstant.v( 0 ) ) );
106: } else {
107: list.add( r=Jimple.v().newReturnStmt( IntConstant.v( 0 ) ) );
108: }
109: } else {
110: throw new RuntimeException( "Wrong return method type: " + method.getReturnType() );
111: }
112: */
113:
114: /*
115: if( method.getName().equals( "<init>" ) || method.getName().equals( "<clinit>" ) ) {
116:
117: Object o = units.getFirst();
118: boolean insertFirst = false;
119: while( true ) {
120: //System.out.println( "Unit: " + o );
121: //System.out.println( "\tClass: " + o.getClass() );
122: if( o == null ) {
123: insertFirst = true;
124: break;
125: }
126: if( o instanceof JInvokeStmt ) {
127: JInvokeStmt stmt = (JInvokeStmt) o;
128: if( (stmt.getInvokeExpr() instanceof SpecialInvokeExpr) ) {
129: SootMethodRef
130: break;
131: }
132: }
133: o = units.getSuccOf( o );
134: }
135: if( insertFirst ) {
136: units.insertBefore( list, units.getFirst() );
137: } else {
138: units.insertAfter( list, o ) ;
139: }
140: } else {
141: */
142: {
143: units.insertBefore(list, units.getFirst());
144: }
145: /*
146: ArrayList toRemove = new ArrayList();
147: for( Iterator sIt = units.iterator(r); sIt.hasNext(); ) {
148: final Stmt s = (Stmt) sIt.next();
149: if(s == r) continue;
150: toRemove.add(s);
151: }
152: for( Iterator sIt = toRemove.iterator(); sIt.hasNext(); ) {
153: final Stmt s = (Stmt) sIt.next();
154: units.getNonPatchingChain().remove(s);
155: }
156: body.getTraps().clear();
157: */
158: }
159: }
|