use of soot.jimple.JimpleBody in project soot by Sable.
the class TypeAssigner method compareTypeAssigners.
private void compareTypeAssigners(Body b, boolean useOlderTypeAssigner) {
JimpleBody jb = (JimpleBody) b, oldJb, newJb;
int size = jb.getUnits().size();
long oldTime, newTime;
if (useOlderTypeAssigner) {
// Use old type assigner last
newJb = (JimpleBody) jb.clone();
newTime = System.currentTimeMillis();
(new soot.jimple.toolkits.typing.fast.TypeResolver(newJb)).inferTypes();
newTime = System.currentTimeMillis() - newTime;
oldTime = System.currentTimeMillis();
TypeResolver.resolve(jb, Scene.v());
oldTime = System.currentTimeMillis() - oldTime;
oldJb = jb;
} else {
// Use new type assigner last
oldJb = (JimpleBody) jb.clone();
oldTime = System.currentTimeMillis();
TypeResolver.resolve(oldJb, Scene.v());
oldTime = System.currentTimeMillis() - oldTime;
newTime = System.currentTimeMillis();
(new soot.jimple.toolkits.typing.fast.TypeResolver(jb)).inferTypes();
newTime = System.currentTimeMillis() - newTime;
newJb = jb;
}
int cmp;
if (newJb.getLocals().size() < oldJb.getLocals().size())
cmp = 2;
else if (newJb.getLocals().size() > oldJb.getLocals().size())
cmp = -2;
else
cmp = compareTypings(oldJb, newJb);
logger.debug("cmp;" + jb.getMethod() + ";" + size + ";" + oldTime + ";" + newTime + ";" + cmp);
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class ConstructorDecl method jimplify2.
/**
* @ast method
* @aspect EmitJimpleRefinements
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/SootJastAddJ/EmitJimpleRefinements.jrag:121
*/
public void jimplify2() {
if (!generate() || sootMethod().hasActiveBody() || (sootMethod().getSource() != null && (sootMethod().getSource() instanceof soot.coffi.CoffiMethodSource)))
return;
JimpleBody body = Jimple.v().newBody(sootMethod());
sootMethod().setActiveBody(body);
Body b = new Body(hostType(), body, this);
b.setLine(this);
for (int i = 0; i < getNumParameter(); i++) getParameter(i).jimplify2(b);
boolean needsInit = true;
if (hasConstructorInvocation()) {
getConstructorInvocation().jimplify2(b);
Stmt stmt = getConstructorInvocation();
if (stmt instanceof ExprStmt) {
ExprStmt exprStmt = (ExprStmt) stmt;
Expr expr = exprStmt.getExpr();
if (!expr.isSuperConstructorAccess())
needsInit = false;
}
}
if (hostType().needsEnclosing()) {
TypeDecl type = hostType().enclosingType();
b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(b.emitThis(hostType()), hostType().getSootField("this$0", type).makeRef()), asLocal(b, Jimple.v().newParameterRef(type.getSootType(), 0))));
}
for (Iterator iter = hostType().enclosingVariables().iterator(); iter.hasNext(); ) {
Variable v = (Variable) iter.next();
ParameterDeclaration p = (ParameterDeclaration) parameterDeclaration("val$" + v.name()).iterator().next();
b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(b.emitThis(hostType()), Scene.v().makeFieldRef(hostType().getSootClassDecl(), "val$" + v.name(), v.type().getSootType(), false)), p.local));
}
if (needsInit) {
TypeDecl typeDecl = hostType();
for (int i = 0; i < typeDecl.getNumBodyDecl(); i++) {
BodyDecl bodyDecl = typeDecl.getBodyDecl(i);
if (bodyDecl instanceof FieldDeclaration && bodyDecl.generate()) {
FieldDeclaration f = (FieldDeclaration) bodyDecl;
if (!f.isStatic() && f.hasInit()) {
soot.Local base = b.emitThis(hostType());
Local l = asLocal(// AssignConversion
b, // AssignConversion
f.getInit().type().emitCastTo(b, f.getInit(), f.type()), f.type().getSootType());
b.setLine(f);
b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(base, f.sootRef()), l));
}
} else if (bodyDecl instanceof InstanceInitializer && bodyDecl.generate()) {
bodyDecl.jimplify2(b);
}
}
}
getBlock().jimplify2(b);
b.add(Jimple.v().newReturnVoidStmt());
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class MethodDecl method jimplify2.
/**
* @ast method
* @aspect EmitJimpleRefinements
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/SootJastAddJ/EmitJimpleRefinements.jrag:100
*/
public void jimplify2() {
if (!generate() || sootMethod().hasActiveBody() || (sootMethod().getSource() != null && (sootMethod().getSource() instanceof soot.coffi.CoffiMethodSource)))
return;
try {
if (hasBlock() && !(hostType().isInterfaceDecl())) {
JimpleBody body = Jimple.v().newBody(sootMethod());
sootMethod().setActiveBody(body);
Body b = new Body(hostType(), body, this);
b.setLine(this);
for (int i = 0; i < getNumParameter(); i++) getParameter(i).jimplify2(b);
getBlock().jimplify2(b);
if (type() instanceof VoidType)
b.add(Jimple.v().newReturnVoidStmt());
}
} catch (RuntimeException e) {
System.err.println("Error generating " + hostType().typeName() + ": " + this);
throw e;
}
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class AbstractASMBackend method getBafBody.
/**
* Gets the baf body for the given SootMethod. This method will first check
* whether the method already has a baf body. If not, it will query the local
* cache. If this fails as well, it will construct a new baf body.
* @param method The method for which to obtain a baf body
* @return The baf body for the given method
*/
protected BafBody getBafBody(SootMethod method) {
final Body activeBody = method.getActiveBody();
if (activeBody instanceof BafBody)
return (BafBody) activeBody;
BafBody body = bafBodyCache.get(method);
if (body != null)
return body;
if (activeBody instanceof JimpleBody) {
body = PackManager.v().convertJimpleBodyToBaf(method);
} else {
throw new RuntimeException("ASM-backend can only translate Baf- and JimpleBodies!");
}
bafBodyCache.put(method, body);
return body;
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class BuildIntermediateAppClasses method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
if (output) {
out.println("Building Intermediate Classes...");
}
BodyBuilder.retrieveAllBodies();
// iterate through application classes, build intermediate classes
Iterator<SootClass> it = Scene.v().getApplicationClasses().snapshotIterator();
while (it.hasNext()) {
List<SootMethod> initMethodsToRewrite = new ArrayList<>();
Map<String, SootMethod> methodsToAdd = new HashMap<>();
SootClass sc = it.next();
SootClass originalSuperclass = sc.getSuperclass();
if (output) {
out.println("Processing " + sc.getName() + " with super " + originalSuperclass.getName());
}
Iterator<SootMethod> methodIterator = sc.methodIterator();
while (methodIterator.hasNext()) {
SootMethod method = methodIterator.next();
if (!method.isConcrete()) {
continue;
}
try {
method.getActiveBody();
} catch (Exception e) {
if (method.retrieveActiveBody() == null)
throw new RuntimeException(method.getSignature() + " has no body. This was not expected dude.");
}
String subSig = method.getSubSignature();
if (subSig.equals("void main(java.lang.String[])") && method.isPublic() && method.isStatic()) {
// skip the main method - it needs to be named 'main'
continue;
} else if (subSig.indexOf("init>(") > 0) {
if (subSig.startsWith("void <init>(")) {
initMethodsToRewrite.add(method);
}
// skip constructors, just add for rewriting at the end
continue;
} else {
Scene.v().releaseActiveHierarchy();
findAccessibleInSuperClassesBySubSig(sc, subSig).ifPresent(m -> methodsToAdd.put(subSig, m));
}
}
if (methodsToAdd.size() > 0) {
final String fullName = ClassRenamer.v().getNewName(ClassRenamer.getPackageName(sc.getName()), null);
if (output) {
out.println("\tBuilding " + fullName);
}
// make non-final soot class
SootClass mediatingClass = new SootClass(fullName, sc.getModifiers() & (~Modifier.FINAL));
Main.IntermediateAppClasses.add(mediatingClass);
mediatingClass.setSuperclass(originalSuperclass);
Scene.v().addClass(mediatingClass);
mediatingClass.setApplicationClass();
mediatingClass.setInScene(true);
ThisRef thisRef = new ThisRef(mediatingClass.getType());
for (String subSig : methodsToAdd.keySet()) {
SootMethod originalSuperclassMethod = methodsToAdd.get(subSig);
List<Type> paramTypes = originalSuperclassMethod.getParameterTypes();
Type returnType = originalSuperclassMethod.getReturnType();
List<SootClass> exceptions = originalSuperclassMethod.getExceptions();
int modifiers = originalSuperclassMethod.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE;
SootMethod newMethod;
{
// build new junk method to call original method
String newMethodName = MethodRenamer.v().getNewName();
newMethod = Scene.v().makeSootMethod(newMethodName, paramTypes, returnType, modifiers, exceptions);
mediatingClass.addMethod(newMethod);
Body body = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(body);
Chain<Local> locals = body.getLocals();
PatchingChain<Unit> units = body.getUnits();
BodyBuilder.buildThisLocal(units, thisRef, locals);
BodyBuilder.buildParameterLocals(units, locals, paramTypes);
if (returnType instanceof VoidType) {
units.add(Jimple.v().newReturnVoidStmt());
} else if (returnType instanceof PrimType) {
units.add(Jimple.v().newReturnStmt(IntConstant.v(0)));
} else {
units.add(Jimple.v().newReturnStmt(NullConstant.v()));
}
newmethods++;
}
// end build new junk method to call original method
{
// build copy of old method
newMethod = Scene.v().makeSootMethod(originalSuperclassMethod.getName(), paramTypes, returnType, modifiers, exceptions);
mediatingClass.addMethod(newMethod);
Body body = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(body);
Chain<Local> locals = body.getLocals();
PatchingChain<Unit> units = body.getUnits();
Local ths = BodyBuilder.buildThisLocal(units, thisRef, locals);
List<Local> args = BodyBuilder.buildParameterLocals(units, locals, paramTypes);
SootMethodRef superclassMethodRef = originalSuperclassMethod.makeRef();
if (returnType instanceof VoidType) {
units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
units.add(Jimple.v().newReturnVoidStmt());
} else {
Local loc = Jimple.v().newLocal("retValue", returnType);
body.getLocals().add(loc);
units.add(Jimple.v().newAssignStmt(loc, Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
units.add(Jimple.v().newReturnStmt(loc));
}
newmethods++;
}
// end build copy of old method
}
sc.setSuperclass(mediatingClass);
// rewrite class init methods to call the proper superclass inits
int i = initMethodsToRewrite.size();
while (i-- > 0) {
SootMethod im = initMethodsToRewrite.remove(i);
Body b = im.getActiveBody();
Local thisLocal = b.getThisLocal();
Iterator<Unit> uIt = b.getUnits().snapshotIterator();
while (uIt.hasNext()) {
for (ValueBox valueBox : uIt.next().getUseBoxes()) {
Value v = valueBox.getValue();
if (v instanceof SpecialInvokeExpr) {
SpecialInvokeExpr sie = (SpecialInvokeExpr) v;
SootMethodRef smr = sie.getMethodRef();
if (sie.getBase().equivTo(thisLocal) && smr.declaringClass().getName().equals(originalSuperclass.getName()) && smr.getSubSignature().getString().startsWith("void " + constructorName)) {
SootMethod newSuperInit;
if (!mediatingClass.declaresMethod(constructorName, smr.parameterTypes())) {
List<Type> paramTypes = smr.parameterTypes();
newSuperInit = Scene.v().makeSootMethod(constructorName, paramTypes, smr.returnType());
mediatingClass.addMethod(newSuperInit);
JimpleBody body = Jimple.v().newBody(newSuperInit);
newSuperInit.setActiveBody(body);
PatchingChain<Unit> initUnits = body.getUnits();
Collection<Local> locals = body.getLocals();
Local ths = BodyBuilder.buildThisLocal(initUnits, thisRef, locals);
List<Local> args = BodyBuilder.buildParameterLocals(initUnits, locals, paramTypes);
initUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, smr, args)));
initUnits.add(Jimple.v().newReturnVoidStmt());
} else {
newSuperInit = mediatingClass.getMethod(constructorName, smr.parameterTypes());
}
sie.setMethodRef(newSuperInit.makeRef());
}
}
}
}
}
// end of rewrite class init methods to call the proper superclass inits
}
}
newclasses = Main.IntermediateAppClasses.size();
Scene.v().releaseActiveHierarchy();
Scene.v().getActiveHierarchy();
Scene.v().setFastHierarchy(new FastHierarchy());
}
Aggregations