use of soot.jimple.InterfaceInvokeExpr in project robovm by robovm.
the class MethodCompiler method invokeExpr.
private Value invokeExpr(Stmt stmt, InvokeExpr expr) {
SootMethodRef methodRef = expr.getMethodRef();
ArrayList<Value> args = new ArrayList<Value>();
args.add(env);
if (!(expr instanceof StaticInvokeExpr)) {
Value base = immediate(stmt, (Immediate) ((InstanceInvokeExpr) expr).getBase());
checkNull(stmt, base);
args.add(base);
}
int i = 0;
for (soot.Value sootArg : (List<soot.Value>) expr.getArgs()) {
Value arg = immediate(stmt, (Immediate) sootArg);
args.add(narrowFromI32Value(stmt, getType(methodRef.parameterType(i)), arg));
i++;
}
Value result = null;
FunctionRef functionRef = config.isDebug() ? null : Intrinsics.getIntrinsic(sootMethod, stmt, expr);
if (functionRef == null) {
Trampoline trampoline = null;
String targetClassName = getInternalName(methodRef.declaringClass());
String methodName = methodRef.name();
String methodDesc = getDescriptor(methodRef);
if (expr instanceof SpecialInvokeExpr) {
soot.Type runtimeType = ((SpecialInvokeExpr) expr).getBase().getType();
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
trampoline = new Invokespecial(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
} else if (expr instanceof StaticInvokeExpr) {
trampoline = new Invokestatic(this.className, targetClassName, methodName, methodDesc);
} else if (expr instanceof VirtualInvokeExpr) {
soot.Type runtimeType = ((VirtualInvokeExpr) expr).getBase().getType();
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
trampoline = new Invokevirtual(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
} else if (expr instanceof InterfaceInvokeExpr) {
trampoline = new Invokeinterface(this.className, targetClassName, methodName, methodDesc);
}
trampolines.add(trampoline);
if (canCallDirectly(expr)) {
SootMethod method = this.sootMethod.getDeclaringClass().getMethod(methodRef.name(), methodRef.parameterTypes(), methodRef.returnType());
if (method.isSynchronized()) {
functionRef = FunctionBuilder.synchronizedWrapper(method).ref();
} else {
functionRef = createMethodFunction(method).ref();
}
} else {
functionRef = trampoline.getFunctionRef();
}
}
result = call(stmt, functionRef, args.toArray(new Value[0]));
if (result != null) {
return widenToI32Value(stmt, result, methodRef.returnType().equals(CharType.v()));
} else {
return null;
}
}
use of soot.jimple.InterfaceInvokeExpr in project robovm by robovm.
the class MethodCompiler method canCallDirectly.
private boolean canCallDirectly(InvokeExpr expr) {
if (expr instanceof InterfaceInvokeExpr) {
// Never possible
return false;
}
SootClass sootClass = this.sootMethod.getDeclaringClass();
SootMethodRef methodRef = expr.getMethodRef();
if (!methodRef.declaringClass().equals(sootClass)) {
return false;
}
try {
SootMethod method = sootClass.getMethod(methodRef.name(), methodRef.parameterTypes(), methodRef.returnType());
if (method.isAbstract()) {
return false;
}
/*
* The method exists and isn't abstract. Non virtual (invokespecial)
* as well as static calls and calls to final methods can be done directly.
*/
if (method.isStatic()) {
// want an exception to be thrown so we need a trampoline.
return expr instanceof StaticInvokeExpr;
}
if (expr instanceof SpecialInvokeExpr) {
return true;
}
if (expr instanceof VirtualInvokeExpr) {
// the method must be private
return Modifier.isFinal(sootClass.getModifiers()) || Modifier.isFinal(method.getModifiers()) || method.isPrivate();
}
return false;
} catch (RuntimeException e) {
// isn't declared in the class.
return false;
}
}
use of soot.jimple.InterfaceInvokeExpr in project soot by Sable.
the class DavaBody method javafy_invoke_expr.
private void javafy_invoke_expr(ValueBox vb) {
InvokeExpr ie = (InvokeExpr) vb.getValue();
String className = ie.getMethodRef().declaringClass().toString();
String packageName = ie.getMethodRef().declaringClass().getJavaPackageName();
String classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
for (int i = 0; i < ie.getArgCount(); i++) {
Value arg = ie.getArg(i);
if (arg instanceof IntConstant)
ie.getArgBox(i).setValue(DIntConstant.v(((IntConstant) arg).value, ie.getMethodRef().parameterType(i)));
else
javafy(ie.getArgBox(i));
}
if (ie instanceof InstanceInvokeExpr) {
javafy(((InstanceInvokeExpr) ie).getBaseBox());
if (ie instanceof VirtualInvokeExpr) {
VirtualInvokeExpr vie = (VirtualInvokeExpr) ie;
vb.setValue(new DVirtualInvokeExpr(vie.getBase(), vie.getMethodRef(), vie.getArgs(), thisLocals));
} else if (ie instanceof SpecialInvokeExpr) {
SpecialInvokeExpr sie = (SpecialInvokeExpr) ie;
vb.setValue(new DSpecialInvokeExpr(sie.getBase(), sie.getMethodRef(), sie.getArgs()));
} else if (ie instanceof InterfaceInvokeExpr) {
InterfaceInvokeExpr iie = (InterfaceInvokeExpr) ie;
vb.setValue(new DInterfaceInvokeExpr(iie.getBase(), iie.getMethodRef(), iie.getArgs()));
} else
throw new RuntimeException("InstanceInvokeExpr " + ie + " not javafied correctly");
} else if (ie instanceof StaticInvokeExpr) {
StaticInvokeExpr sie = (StaticInvokeExpr) ie;
if (sie instanceof NewInvokeExpr) {
NewInvokeExpr nie = (NewInvokeExpr) sie;
RefType rt = nie.getBaseType();
className = rt.getSootClass().toString();
packageName = rt.getSootClass().getJavaPackageName();
classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
vb.setValue(new DNewInvokeExpr((RefType) nie.getType(), nie.getMethodRef(), nie.getArgs()));
} else {
SootMethodRef methodRef = sie.getMethodRef();
className = methodRef.declaringClass().toString();
packageName = methodRef.declaringClass().getJavaPackageName();
classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
// addPackage(methodRef.declaringClass().getJavaPackageName());
vb.setValue(new DStaticInvokeExpr(methodRef, sie.getArgs()));
}
} else
throw new RuntimeException("InvokeExpr " + ie + " not javafied correctly");
}
use of soot.jimple.InterfaceInvokeExpr in project soot by Sable.
the class ExceptionChecker method checkInvokeExpr.
protected void checkInvokeExpr(Body b, InvokeExpr ie, Stmt s) {
if (ie instanceof InstanceInvokeExpr && ((InstanceInvokeExpr) ie).getBase().getType() instanceof ArrayType && ie.getMethodRef().name().equals("clone") && ie.getMethodRef().parameterTypes().size() == 0)
// the call is to the clone() method of an array type, which
return;
// is defined not to throw any exceptions; if we left this to
// normal resolution we'd get the method in Object which does
// throw CloneNotSupportedException
List exceptions = ie instanceof InterfaceInvokeExpr ? // the method in supertypes.
getExceptionSpec(ie.getMethodRef().declaringClass(), ie.getMethodRef().getSubSignature()) : // Otherwise, we just do normal resolution.
ie.getMethod().getExceptionsUnsafe();
if (exceptions == null)
return;
Iterator it = exceptions.iterator();
while (it.hasNext()) {
SootClass sc = (SootClass) it.next();
if (isThrowDeclared(b, sc) || isExceptionCaught(b, s, sc.getType()))
continue;
if (reporter != null) {
if (s instanceof InvokeStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) s.getTag("SourceLnPosTag")));
} else if (s instanceof AssignStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) ((AssignStmt) s).getRightOpBox().getTag("SourceLnPosTag")));
}
}
}
}
use of soot.jimple.InterfaceInvokeExpr in project soot by Sable.
the class OnTheFlyJimpleBasedICFG method main.
public static void main(String[] args) {
PackManager.v().getPack("wjtp").add(new Transform("wjtp.onflyicfg", new SceneTransformer() {
@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
if (Scene.v().hasCallGraph())
throw new RuntimeException("call graph present!");
loadAllClassesOnClassPathToSignatures();
SootMethod mainMethod = Scene.v().getMainMethod();
OnTheFlyJimpleBasedICFG icfg = new OnTheFlyJimpleBasedICFG(mainMethod);
Set<SootMethod> worklist = new LinkedHashSet<SootMethod>();
Set<SootMethod> visited = new HashSet<SootMethod>();
worklist.add(mainMethod);
int monomorphic = 0, polymorphic = 0;
while (!worklist.isEmpty()) {
Iterator<SootMethod> iter = worklist.iterator();
SootMethod currMethod = iter.next();
iter.remove();
visited.add(currMethod);
System.err.println(currMethod);
// MUST call this method to initialize ICFG for every method
Body body = currMethod.getActiveBody();
if (body == null)
continue;
for (Unit u : body.getUnits()) {
Stmt s = (Stmt) u;
if (s.containsInvokeExpr()) {
Set<SootMethod> calleesOfCallAt = icfg.getCalleesOfCallAt(s);
if (s.getInvokeExpr() instanceof VirtualInvokeExpr || s.getInvokeExpr() instanceof InterfaceInvokeExpr) {
if (calleesOfCallAt.size() <= 1)
monomorphic++;
else
polymorphic++;
System.err.println("mono: " + monomorphic + " poly: " + polymorphic);
}
for (SootMethod callee : calleesOfCallAt) {
if (!visited.contains(callee)) {
System.err.println(callee);
// worklist.add(callee);
}
}
}
}
}
}
}));
Options.v().set_on_the_fly(true);
soot.Main.main(args);
}
Aggregations