001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2004 Jennifer Lhotak
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: package soot.javaToJimple;
021:
022: import java.util.*;
023:
024: public class AssertClassMethodSource implements soot.MethodSource {
025:
026: public soot.Body getBody(soot.SootMethod sootMethod,
027: String phaseName) {
028:
029: soot.Body classBody = soot.jimple.Jimple.v()
030: .newBody(sootMethod);
031:
032: // static invoke of forName
033: soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v()
034: .newParameterRef(soot.RefType.v("java.lang.String"), 0);
035:
036: soot.Local paramLocal = soot.jimple.Jimple.v().newLocal("$r0",
037: soot.RefType.v("java.lang.String"));
038: classBody.getLocals().add(paramLocal);
039: soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(
040: paramLocal, paramRef);
041: classBody.getUnits().add(stmt);
042:
043: ArrayList paramTypes = new ArrayList();
044: paramTypes.add(soot.RefType.v("java.lang.String"));
045: soot.SootMethodRef methodToInvoke = soot.Scene.v()
046: .makeMethodRef(
047: soot.Scene.v().getSootClass("java.lang.Class"),
048: "forName", paramTypes,
049: soot.RefType.v("java.lang.Class"), true);
050: soot.Local invokeLocal = soot.jimple.Jimple.v().newLocal("$r1",
051: soot.RefType.v("java.lang.Class"));
052: classBody.getLocals().add(invokeLocal);
053: ArrayList params = new ArrayList();
054: params.add(paramLocal);
055: soot.jimple.Expr invokeExpr = soot.jimple.Jimple.v()
056: .newStaticInvokeExpr(methodToInvoke, params);
057: soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(
058: invokeLocal, invokeExpr);
059: classBody.getUnits().add(assign);
060:
061: // return
062: soot.jimple.Stmt retStmt = soot.jimple.Jimple.v()
063: .newReturnStmt(invokeLocal);
064: classBody.getUnits().add(retStmt);
065:
066: // catch
067: soot.Local catchRefLocal = soot.jimple.Jimple.v().newLocal(
068: "$r2",
069: soot.RefType.v("java.lang.ClassNotFoundException"));
070: classBody.getLocals().add(catchRefLocal);
071: soot.jimple.CaughtExceptionRef caughtRef = soot.jimple.Jimple
072: .v().newCaughtExceptionRef();
073: soot.jimple.Stmt caughtIdentity = soot.jimple.Jimple.v()
074: .newIdentityStmt(catchRefLocal, caughtRef);
075: classBody.getUnits().add(caughtIdentity);
076:
077: // new no class def found error
078: soot.Local noClassDefLocal = soot.jimple.Jimple.v()
079: .newLocal(
080: "$r3",
081: soot.RefType
082: .v("java.lang.NoClassDefFoundError"));
083: classBody.getLocals().add(noClassDefLocal);
084: soot.jimple.Expr newExpr = soot.jimple.Jimple.v().newNewExpr(
085: soot.RefType.v("java.lang.NoClassDefFoundError"));
086: soot.jimple.Stmt noClassDefAssign = soot.jimple.Jimple.v()
087: .newAssignStmt(noClassDefLocal, newExpr);
088: classBody.getUnits().add(noClassDefAssign);
089:
090: // no class def found invoke
091: paramTypes = new ArrayList();
092: soot.SootMethodRef initMethToInvoke = soot.Scene.v()
093: .makeMethodRef(
094: soot.Scene.v().getSootClass(
095: "java.lang.NoClassDefFoundError"),
096: "<init>", paramTypes, soot.VoidType.v(), false);
097: params = new ArrayList();
098: soot.jimple.Expr initInvoke = soot.jimple.Jimple.v()
099: .newSpecialInvokeExpr(noClassDefLocal,
100: initMethToInvoke, params);
101: soot.jimple.Stmt initStmt = soot.jimple.Jimple.v()
102: .newInvokeStmt(initInvoke);
103: classBody.getUnits().add(initStmt);
104:
105: // get exception message
106: soot.Local throwLocal = soot.jimple.Jimple.v().newLocal("$r4",
107: soot.RefType.v("java.lang.Throwable"));
108: classBody.getLocals().add(throwLocal);
109: paramTypes = new ArrayList();
110: paramTypes.add(soot.RefType.v("java.lang.Throwable"));
111: params = new ArrayList();
112: params.add(catchRefLocal);
113: soot.SootMethodRef messageMethToInvoke = soot.Scene.v()
114: .makeMethodRef(
115: soot.Scene.v().getSootClass(
116: "java.lang.Throwable"), "initCause",
117: paramTypes,
118: soot.RefType.v("java.lang.Throwable"), false);
119:
120: soot.jimple.Expr messageInvoke = soot.jimple.Jimple.v()
121: .newVirtualInvokeExpr(noClassDefLocal,
122: messageMethToInvoke, params);
123: soot.jimple.Stmt messageAssign = soot.jimple.Jimple.v()
124: .newAssignStmt(throwLocal, messageInvoke);
125: classBody.getUnits().add(messageAssign);
126:
127: // throw
128: soot.jimple.Stmt throwStmt = soot.jimple.Jimple.v()
129: .newThrowStmt(throwLocal);
130: throwStmt.addTag(new soot.tagkit.ThrowCreatedByCompilerTag());
131: classBody.getUnits().add(throwStmt);
132:
133: // trap
134: soot.Trap trap = soot.jimple.Jimple.v().newTrap(
135: soot.Scene.v().getSootClass(
136: "java.lang.ClassNotFoundException"), assign,
137: retStmt, caughtIdentity);
138: classBody.getTraps().add(trap);
139:
140: return classBody;
141:
142: }
143: }
|