Search in sources :

Example 1 with InterfaceInvokeExpr

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;
    }
}
Also used : Trampoline(org.robovm.compiler.trampoline.Trampoline) SootMethodRef(soot.SootMethodRef) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) Invokeinterface(org.robovm.compiler.trampoline.Invokeinterface) Invokespecial(org.robovm.compiler.trampoline.Invokespecial) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Invokestatic(org.robovm.compiler.trampoline.Invokestatic) Value(org.robovm.compiler.llvm.Value) SootMethod(soot.SootMethod) ArrayList(java.util.ArrayList) List(java.util.List) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) Invokevirtual(org.robovm.compiler.trampoline.Invokevirtual) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 2 with InterfaceInvokeExpr

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;
    }
}
Also used : StaticInvokeExpr(soot.jimple.StaticInvokeExpr) SootMethodRef(soot.SootMethodRef) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SootMethod(soot.SootMethod) SootClass(soot.SootClass) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr)

Example 3 with InterfaceInvokeExpr

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");
}
Also used : DNewInvokeExpr(soot.dava.internal.javaRep.DNewInvokeExpr) NewInvokeExpr(soot.grimp.NewInvokeExpr) DSpecialInvokeExpr(soot.dava.internal.javaRep.DSpecialInvokeExpr) SootMethodRef(soot.SootMethodRef) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) DSpecialInvokeExpr(soot.dava.internal.javaRep.DSpecialInvokeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) DInterfaceInvokeExpr(soot.dava.internal.javaRep.DInterfaceInvokeExpr) DInterfaceInvokeExpr(soot.dava.internal.javaRep.DInterfaceInvokeExpr) DVirtualInvokeExpr(soot.dava.internal.javaRep.DVirtualInvokeExpr) DStaticInvokeExpr(soot.dava.internal.javaRep.DStaticInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RefType(soot.RefType) DNewInvokeExpr(soot.dava.internal.javaRep.DNewInvokeExpr) DNewInvokeExpr(soot.dava.internal.javaRep.DNewInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) DInterfaceInvokeExpr(soot.dava.internal.javaRep.DInterfaceInvokeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) NewInvokeExpr(soot.grimp.NewInvokeExpr) DVirtualInvokeExpr(soot.dava.internal.javaRep.DVirtualInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) DStaticInvokeExpr(soot.dava.internal.javaRep.DStaticInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) DSpecialInvokeExpr(soot.dava.internal.javaRep.DSpecialInvokeExpr) DStaticInvokeExpr(soot.dava.internal.javaRep.DStaticInvokeExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) DIntConstant(soot.dava.internal.javaRep.DIntConstant) DVirtualInvokeExpr(soot.dava.internal.javaRep.DVirtualInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr)

Example 4 with InterfaceInvokeExpr

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")));
            }
        }
    }
}
Also used : ArrayType(soot.ArrayType) SourceLnPosTag(soot.tagkit.SourceLnPosTag) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) Iterator(java.util.Iterator) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) List(java.util.List) SootClass(soot.SootClass)

Example 5 with InterfaceInvokeExpr

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) Unit(soot.Unit) SceneTransformer(soot.SceneTransformer) Stmt(soot.jimple.Stmt) SootMethod(soot.SootMethod) Transform(soot.Transform) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) HashMap(java.util.HashMap) Map(java.util.Map) Body(soot.Body) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

InterfaceInvokeExpr (soot.jimple.InterfaceInvokeExpr)8 VirtualInvokeExpr (soot.jimple.VirtualInvokeExpr)6 SootMethod (soot.SootMethod)5 SootMethodRef (soot.SootMethodRef)5 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)5 StaticInvokeExpr (soot.jimple.StaticInvokeExpr)5 SootClass (soot.SootClass)4 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)4 Local (soot.Local)3 Unit (soot.Unit)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Body (soot.Body)2 Value (soot.Value)2 InvokeExpr (soot.jimple.InvokeExpr)2 JimpleBody (soot.jimple.JimpleBody)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1