Search in sources :

Example 96 with SootClass

use of soot.SootClass in project soot by Sable.

the class ReflectiveCallsInliner method createNewMethod.

@SuppressWarnings("unchecked")
private SootMethod createNewMethod(Kind callKind, String target, Type fieldSetGetType) {
    List<Type> parameterTypes = new LinkedList<Type>();
    Type returnType = null;
    switch(callKind) {
        case ClassForName:
            returnType = RefType.v("java.lang.Class");
            break;
        case ClassNewInstance:
            returnType = RefType.v("java.lang.Object");
            break;
        case ConstructorNewInstance:
            parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
            returnType = RefType.v("java.lang.Object");
            break;
        case MethodInvoke:
            parameterTypes.add(RefType.v("java.lang.Object"));
            parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
            returnType = RefType.v("java.lang.Object");
            break;
        case FieldSet:
            parameterTypes.add(RefType.v("java.lang.Object"));
            parameterTypes.add(fieldSetGetType);
            returnType = VoidType.v();
            break;
        case FieldGet:
            parameterTypes.add(RefType.v("java.lang.Object"));
            returnType = fieldSetGetType;
            break;
        default:
            throw new IllegalStateException();
    }
    SootMethod newMethod = Scene.v().makeSootMethod("reflectiveCall" + (callNum++), parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC);
    Body newBody = Jimple.v().newBody(newMethod);
    newMethod.setActiveBody(newBody);
    reflectiveCallsClass.addMethod(newMethod);
    PatchingChain<Unit> newUnits = newBody.getUnits();
    LocalGenerator localGen = new LocalGenerator(newBody);
    Local freshLocal;
    Value replacement = null;
    Local[] paramLocals = null;
    switch(callKind) {
        case ClassForName:
            {
                // replace by: <Class constant for <target>>
                freshLocal = localGen.generateLocal(RefType.v("java.lang.Class"));
                replacement = ClassConstant.v(target.replace('.', '/'));
                break;
            }
        case ClassNewInstance:
            {
                // replace by: new <target>
                RefType targetType = RefType.v(target);
                freshLocal = localGen.generateLocal(targetType);
                replacement = Jimple.v().newNewExpr(targetType);
                break;
            }
        case ConstructorNewInstance:
            {
                /*
			 * replace r=constr.newInstance(args) by: Object p0 = args[0]; ...
			 * Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an = (Tn)pn;
			 */
                SootMethod constructor = Scene.v().getMethod(target);
                paramLocals = new Local[constructor.getParameterCount()];
                if (constructor.getParameterCount() > 0) {
                    // argArrayLocal = @parameter-0
                    ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
                    Local argArrayLocal = localGen.generateLocal(arrayType);
                    newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 0)));
                    int i = 0;
                    for (Type paramType : ((Collection<Type>) constructor.getParameterTypes())) {
                        paramLocals[i] = localGen.generateLocal(paramType);
                        unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
                        i++;
                    }
                }
                RefType targetType = constructor.getDeclaringClass().getType();
                freshLocal = localGen.generateLocal(targetType);
                replacement = Jimple.v().newNewExpr(targetType);
                break;
            }
        case MethodInvoke:
            {
                /*
			 * replace r=m.invoke(obj,args) by: T recv = (T)obj; Object p0 =
			 * args[0]; ... Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an =
			 * (Tn)pn;
			 */
                SootMethod method = Scene.v().getMethod(target);
                // recvObject = @parameter-0
                RefType objectType = RefType.v("java.lang.Object");
                Local recvObject = localGen.generateLocal(objectType);
                newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
                paramLocals = new Local[method.getParameterCount()];
                if (method.getParameterCount() > 0) {
                    // argArrayLocal = @parameter-1
                    ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
                    Local argArrayLocal = localGen.generateLocal(arrayType);
                    newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 1)));
                    int i = 0;
                    for (Type paramType : ((Collection<Type>) method.getParameterTypes())) {
                        paramLocals[i] = localGen.generateLocal(paramType);
                        unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
                        i++;
                    }
                }
                RefType targetType = method.getDeclaringClass().getType();
                freshLocal = localGen.generateLocal(targetType);
                replacement = Jimple.v().newCastExpr(recvObject, method.getDeclaringClass().getType());
                break;
            }
        case FieldSet:
        case FieldGet:
            {
                /*
			 * replace f.set(o,v) by: Object obj = @parameter-0; T freshLocal =
			 * (T)obj;
			 */
                RefType objectType = RefType.v("java.lang.Object");
                Local recvObject = localGen.generateLocal(objectType);
                newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
                SootField field = Scene.v().getField(target);
                freshLocal = localGen.generateLocal(field.getDeclaringClass().getType());
                replacement = Jimple.v().newCastExpr(recvObject, field.getDeclaringClass().getType());
                break;
            }
        default:
            throw new InternalError("Unknown kind of reflective call " + callKind);
    }
    AssignStmt replStmt = Jimple.v().newAssignStmt(freshLocal, replacement);
    newUnits.add(replStmt);
    Local retLocal = localGen.generateLocal(returnType);
    switch(callKind) {
        case ClassForName:
            {
                // add: retLocal = freshLocal;
                newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
                break;
            }
        case ClassNewInstance:
            {
                // add: freshLocal.<init>()
                SootClass targetClass = Scene.v().getSootClass(target);
                SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, Scene.v().makeMethodRef(targetClass, SootMethod.constructorName, Collections.<Type>emptyList(), VoidType.v(), false));
                InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
                newUnits.add(constrCallStmt2);
                // add: retLocal = freshLocal
                newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
                break;
            }
        case ConstructorNewInstance:
            {
                // add: freshLocal.<target>(a0,...,an);
                SootMethod constructor = Scene.v().getMethod(target);
                SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, constructor.makeRef(), Arrays.asList(paramLocals));
                InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
                newUnits.add(constrCallStmt2);
                // add: retLocal = freshLocal
                newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
                break;
            }
        case MethodInvoke:
            {
                // add: freshLocal=recv.<target>(a0,...,an);
                SootMethod method = Scene.v().getMethod(target);
                InvokeExpr invokeExpr;
                if (method.isStatic())
                    invokeExpr = Jimple.v().newStaticInvokeExpr(method.makeRef(), Arrays.asList(paramLocals));
                else
                    invokeExpr = Jimple.v().newVirtualInvokeExpr(freshLocal, method.makeRef(), Arrays.<Value>asList(paramLocals));
                if (method.getReturnType().equals(VoidType.v())) {
                    // method returns null; simply invoke it and return null
                    InvokeStmt invokeStmt = Jimple.v().newInvokeStmt(invokeExpr);
                    newUnits.add(invokeStmt);
                    AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, NullConstant.v());
                    newUnits.add(assignStmt);
                } else {
                    AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, invokeExpr);
                    newUnits.add(assignStmt);
                }
                break;
            }
        case FieldSet:
            {
                // add freshLocal.<f> = v;
                Local value = localGen.generateLocal(fieldSetGetType);
                newUnits.insertBeforeNoRedirect(Jimple.v().newIdentityStmt(value, Jimple.v().newParameterRef(fieldSetGetType, 1)), replStmt);
                SootField field = Scene.v().getField(target);
                Local boxedOrCasted = localGen.generateLocal(field.getType());
                insertCastOrUnboxingCode(boxedOrCasted, value, newUnits);
                FieldRef fieldRef;
                if (field.isStatic()) {
                    fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
                } else {
                    fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
                }
                newUnits.add(Jimple.v().newAssignStmt(fieldRef, boxedOrCasted));
                break;
            }
        case FieldGet:
            {
                /*
			 * add: T2 temp = recv.<f>; return temp;
			 */
                SootField field = Scene.v().getField(target);
                Local value = localGen.generateLocal(field.getType());
                FieldRef fieldRef;
                if (field.isStatic()) {
                    fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
                } else {
                    fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
                }
                newUnits.add(Jimple.v().newAssignStmt(value, fieldRef));
                insertCastOrBoxingCode(retLocal, value, newUnits);
                break;
            }
    }
    if (!returnType.equals(VoidType.v()))
        newUnits.add(Jimple.v().newReturnStmt(retLocal));
    if (Options.v().validate())
        newBody.validate();
    cleanup(newBody);
    return newMethod;
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) FieldRef(soot.jimple.FieldRef) SootFieldRef(soot.SootFieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) Local(soot.Local) Unit(soot.Unit) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) RefType(soot.RefType) ArrayType(soot.ArrayType) RefType(soot.RefType) BooleanType(soot.BooleanType) Type(soot.Type) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) VoidType(soot.VoidType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Value(soot.Value) SootMethod(soot.SootMethod) Collection(java.util.Collection) SootField(soot.SootField) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody)

Example 97 with SootClass

use of soot.SootClass in project soot by Sable.

the class OnTheFlyJimpleBasedICFG method initForMethod.

protected Body initForMethod(SootMethod m) {
    assert Scene.v().hasFastHierarchy();
    Body b = null;
    if (m.isConcrete()) {
        SootClass declaringClass = m.getDeclaringClass();
        ensureClassHasBodies(declaringClass);
        synchronized (Scene.v()) {
            b = m.retrieveActiveBody();
        }
        if (b != null) {
            for (Unit u : b.getUnits()) {
                if (unitToOwner.put(u, b) != null) {
                    // simply skip the rest
                    break;
                }
            }
        }
    }
    assert Scene.v().hasFastHierarchy();
    return b;
}
Also used : SootClass(soot.SootClass) Unit(soot.Unit) Body(soot.Body)

Example 98 with SootClass

use of soot.SootClass in project soot by Sable.

the class TypeDecl method refined_EmitJimple_TypeDecl_getSootClassDecl.

/**
 * @ast method
 * @aspect EmitJimple
 * @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/EmitJimple.jrag:32
 */
private SootClass refined_EmitJimple_TypeDecl_getSootClassDecl() {
    if (compilationUnit().fromSource()) {
        return sootClass();
    } else {
        if (options().verbose())
            System.out.println("Loading .class file " + jvmName());
        SootClass sc = Scene.v().loadClass(jvmName(), SootClass.SIGNATURES);
        sc.setLibraryClass();
        return sc;
    }
}
Also used : SootClass(soot.SootClass)

Example 99 with SootClass

use of soot.SootClass in project robovm by robovm.

the class ObjCMemberPlugin method init.

private void init(Config config) {
    if (initialized) {
        return;
    }
    this.config = config;
    if (config.getClazzes().load(OBJC_OBJECT.replace('.', '/')) == null) {
        initialized = true;
        return;
    }
    SootResolver r = SootResolver.v();
    // These have to be resolved to HIERARCHY so that isPhantom() works
    // properly
    org_robovm_objc_ObjCObject = r.resolveClass(OBJC_OBJECT, SootClass.HIERARCHY);
    org_robovm_objc_ObjCExtensions = r.resolveClass(OBJC_EXTENSIONS, SootClass.HIERARCHY);
    // These only have to be DANGLING
    org_robovm_objc_ObjCClass = r.makeClassRef(OBJC_CLASS);
    org_robovm_objc_ObjCSuper = r.makeClassRef(OBJC_SUPER);
    org_robovm_objc_ObjCRuntime = r.makeClassRef(OBJC_RUNTIME);
    org_robovm_objc_Selector = r.makeClassRef(SELECTOR);
    org_robovm_apple_foundation_NSObject = r.makeClassRef(NS_OBJECT);
    org_robovm_apple_foundation_NSObject$Marshaler = r.makeClassRef(NS_OBJECT$MARSHALER);
    org_robovm_apple_foundation_NSString$AsStringMarshaler = r.makeClassRef(NS_STRING$AS_STRING_MARSHALER);
    org_robovm_objc_$M = r.makeClassRef($M);
    org_robovm_apple_uikit_UIEvent = r.makeClassRef(UI_EVENT);
    org_robovm_apple_foundation_NSArray = r.makeClassRef(NS_ARRAY);
    SootClass java_lang_Object = r.makeClassRef("java.lang.Object");
    java_lang_String = r.makeClassRef("java.lang.String");
    java_lang_Class = r.makeClassRef("java.lang.Class");
    org_robovm_objc_Selector_register = Scene.v().makeMethodRef(org_robovm_objc_Selector, "register", Arrays.<Type>asList(java_lang_String.getType()), org_robovm_objc_Selector.getType(), true);
    org_robovm_objc_ObjCObject_getSuper = Scene.v().makeMethodRef(org_robovm_objc_ObjCObject, "getSuper", Collections.<Type>emptyList(), org_robovm_objc_ObjCSuper.getType(), false);
    org_robovm_objc_ObjCObject_updateStrongRef = Scene.v().makeMethodRef(org_robovm_objc_ObjCObject, "updateStrongRef", Arrays.<Type>asList(java_lang_Object.getType(), java_lang_Object.getType()), VoidType.v(), false);
    org_robovm_objc_ObjCClass_getByType = Scene.v().makeMethodRef(org_robovm_objc_ObjCClass, "getByType", Arrays.<Type>asList(java_lang_Class.getType()), org_robovm_objc_ObjCClass.getType(), true);
    org_robovm_objc_ObjCRuntime_bind = Scene.v().makeMethodRef(org_robovm_objc_ObjCRuntime, "bind", Arrays.<Type>asList(java_lang_Class.getType()), VoidType.v(), true);
    org_robovm_objc_ObjCObject_customClass = Scene.v().makeFieldRef(org_robovm_objc_ObjCObject, "customClass", BooleanType.v(), false);
    org_robovm_objc_ObjCExtensions_updateStrongRef = Scene.v().makeMethodRef(org_robovm_objc_ObjCExtensions, "updateStrongRef", Arrays.<Type>asList(org_robovm_objc_ObjCObject.getType(), java_lang_Object.getType(), java_lang_Object.getType()), VoidType.v(), true);
    initialized = true;
}
Also used : RefType(soot.RefType) BooleanType(soot.BooleanType) SootMethodType(org.robovm.compiler.util.generic.SootMethodType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) LongType(soot.LongType) RefLikeType(soot.RefLikeType) PrimType(soot.PrimType) VoidType(soot.VoidType) SootResolver(soot.SootResolver) SootClass(soot.SootClass)

Example 100 with SootClass

use of soot.SootClass in project robovm by robovm.

the class ObjCMemberPlugin method beforeClass.

@Override
public void beforeClass(Config config, Clazz clazz, ModuleBuilder moduleBuilder) {
    init(config);
    SootClass sootClass = clazz.getSootClass();
    boolean extensions = false;
    if (!sootClass.isInterface() && (isObjCObject(sootClass) || (extensions = isObjCExtensions(sootClass)))) {
        Set<String> selectors = new TreeSet<>();
        Set<String> overridables = new HashSet<>();
        for (SootMethod method : sootClass.getMethods()) {
            if (!"<clinit>".equals(method.getName()) && !"<init>".equals(method.getName())) {
                transformMethod(config, clazz, sootClass, method, selectors, overridables, extensions);
            }
        }
        addBindCall(sootClass);
        if (!extensions) {
            addObjCClassField(sootClass);
        }
        registerSelectors(sootClass, selectors);
    }
}
Also used : TreeSet(java.util.TreeSet) SootMethod(soot.SootMethod) SootClass(soot.SootClass) HashSet(java.util.HashSet)

Aggregations

SootClass (soot.SootClass)194 SootMethod (soot.SootMethod)99 RefType (soot.RefType)69 ArrayList (java.util.ArrayList)60 Type (soot.Type)57 VoidType (soot.VoidType)33 ArrayType (soot.ArrayType)32 Iterator (java.util.Iterator)29 BooleanType (soot.BooleanType)29 DoubleType (soot.DoubleType)29 LongType (soot.LongType)29 Value (soot.Value)29 FloatType (soot.FloatType)28 Local (soot.Local)27 SootField (soot.SootField)27 List (java.util.List)26 CharType (soot.CharType)26 IntType (soot.IntType)26 ByteType (soot.ByteType)25 PrimType (soot.PrimType)23