Search in sources :

Example 21 with PrimType

use of soot.PrimType in project robovm by robovm.

the class ClassCompiler method createClassInfoStruct.

private StructureConstant createClassInfoStruct() {
    int flags = 0;
    if (Modifier.isPublic(sootClass.getModifiers())) {
        flags |= CI_PUBLIC;
    }
    if (Modifier.isFinal(sootClass.getModifiers())) {
        flags |= CI_FINAL;
    }
    if (Modifier.isInterface(sootClass.getModifiers())) {
        flags |= CI_INTERFACE;
    }
    if (Modifier.isAbstract(sootClass.getModifiers())) {
        flags |= CI_ABSTRACT;
    }
    if ((sootClass.getModifiers() & 0x1000) > 0) {
        flags |= CI_SYNTHETIC;
    }
    if (Modifier.isAnnotation(sootClass.getModifiers())) {
        flags |= CI_ANNOTATION;
    }
    if (Modifier.isEnum(sootClass.getModifiers())) {
        flags |= CI_ENUM;
    }
    if (attributesEncoder.classHasAttributes()) {
        flags |= CI_ATTRIBUTES;
    }
    if (hasFinalizer(sootClass)) {
        flags |= CI_FINALIZABLE;
    }
    // Create the ClassInfoHeader structure.
    StructureConstantBuilder header = new StructureConstantBuilder();
    // Points to the runtime Class struct
    header.add(new NullConstant(I8_PTR));
    header.add(new IntegerConstant(flags));
    header.add(getString(getInternalName(sootClass)));
    if (sootClass.declaresMethod("<clinit>", Collections.emptyList(), VoidType.v())) {
        SootMethod method = sootClass.getMethod("<clinit>", Collections.emptyList(), VoidType.v());
        header.add(new FunctionRef(Symbols.methodSymbol(method), getFunctionType(method)));
    } else {
        header.add(new NullConstant(I8_PTR));
    }
    mb.addGlobal(new Global(Symbols.typeInfoSymbol(getInternalName(sootClass)), Linkage.external, I8_PTR, true));
    // TypeInfo* generated by Linker
    header.add(new GlobalRef(Symbols.typeInfoSymbol(getInternalName(sootClass)), I8_PTR));
    if (!sootClass.isInterface()) {
        header.add(createVTableStruct());
    } else {
        header.add(createITableStruct());
    }
    header.add(createITablesStruct());
    header.add(sizeof(classType));
    header.add(sizeof(instanceType));
    if (!instanceFields.isEmpty()) {
        header.add(offsetof(instanceType, 1, 1));
    } else {
        header.add(sizeof(instanceType));
    }
    header.add(new IntegerConstant((short) countReferences(classFields)));
    header.add(new IntegerConstant((short) countReferences(instanceFields)));
    PackedStructureConstantBuilder body = new PackedStructureConstantBuilder();
    body.add(new IntegerConstant((short) sootClass.getInterfaceCount()));
    body.add(new IntegerConstant((short) sootClass.getFieldCount()));
    body.add(new IntegerConstant((short) sootClass.getMethodCount()));
    if (!sootClass.isInterface()) {
        body.add(getStringOrNull(sootClass.hasSuperclass() ? getInternalName(sootClass.getSuperclass()) : null));
    }
    if (attributesEncoder.classHasAttributes()) {
        body.add(new ConstantBitcast(attributesEncoder.getClassAttributes().ref(), I8_PTR));
    }
    for (SootClass s : sootClass.getInterfaces()) {
        body.add(getString(getInternalName(s)));
    }
    for (SootField f : sootClass.getFields()) {
        flags = 0;
        soot.Type t = f.getType();
        if (t instanceof PrimType) {
            if (t.equals(BooleanType.v())) {
                flags |= DESC_Z;
            } else if (t.equals(ByteType.v())) {
                flags |= DESC_B;
            } else if (t.equals(ShortType.v())) {
                flags |= DESC_S;
            } else if (t.equals(CharType.v())) {
                flags |= DESC_C;
            } else if (t.equals(IntType.v())) {
                flags |= DESC_I;
            } else if (t.equals(LongType.v())) {
                flags |= DESC_J;
            } else if (t.equals(FloatType.v())) {
                flags |= DESC_F;
            } else if (t.equals(DoubleType.v())) {
                flags |= DESC_D;
            }
            flags <<= 12;
        }
        if (Modifier.isPublic(f.getModifiers())) {
            flags |= FI_PUBLIC;
        } else if (Modifier.isPrivate(f.getModifiers())) {
            flags |= FI_PRIVATE;
        } else if (Modifier.isProtected(f.getModifiers())) {
            flags |= FI_PROTECTED;
        }
        if (Modifier.isStatic(f.getModifiers())) {
            flags |= FI_STATIC;
        }
        if (Modifier.isFinal(f.getModifiers())) {
            flags |= FI_FINAL;
        }
        if (Modifier.isVolatile(f.getModifiers())) {
            flags |= FI_VOLATILE;
        }
        if (Modifier.isTransient(f.getModifiers())) {
            flags |= FI_TRANSIENT;
        }
        if ((f.getModifiers() & 0x1000) > 0) {
            flags |= FI_SYNTHETIC;
        }
        if (Modifier.isEnum(f.getModifiers())) {
            flags |= FI_ENUM;
        }
        if (attributesEncoder.fieldHasAttributes(f)) {
            flags |= FI_ATTRIBUTES;
        }
        body.add(new IntegerConstant((short) flags));
        body.add(getString(f.getName()));
        if (!(t instanceof PrimType)) {
            body.add(getString(getDescriptor(f)));
        }
        if (f.isStatic()) {
            int index = classFields.indexOf(f);
            body.add(offsetof(classType, 1, index, 1));
        } else {
            int index = instanceFields.indexOf(f);
            body.add(offsetof(instanceType, 1, 1 + index, 1));
        }
        if (attributesEncoder.fieldHasAttributes(f)) {
            body.add(new ConstantBitcast(attributesEncoder.getFieldAttributes(f).ref(), I8_PTR));
        }
    }
    VTable vtable = !sootClass.isInterface() ? config.getVTableCache().get(sootClass) : null;
    ITable itable = sootClass.isInterface() ? config.getITableCache().get(sootClass) : null;
    ;
    for (SootMethod m : sootClass.getMethods()) {
        soot.Type t = m.getReturnType();
        flags = 0;
        if (Modifier.isPublic(m.getModifiers())) {
            flags |= MI_PUBLIC;
        } else if (Modifier.isPrivate(m.getModifiers())) {
            flags |= MI_PRIVATE;
        } else if (Modifier.isProtected(m.getModifiers())) {
            flags |= MI_PROTECTED;
        }
        if (Modifier.isStatic(m.getModifiers())) {
            flags |= MI_STATIC;
        }
        if (Modifier.isFinal(m.getModifiers())) {
            flags |= MI_FINAL;
        }
        if (Modifier.isSynchronized(m.getModifiers())) {
            flags |= MI_SYNCHRONIZED;
        }
        if ((m.getModifiers() & 0x0040) > 0) {
            flags |= MI_BRIDGE;
        }
        if ((m.getModifiers() & 0x0080) > 0) {
            flags |= MI_VARARGS;
        }
        if (Modifier.isNative(m.getModifiers())) {
            if (!isStruct(sootClass) && !hasStructMemberAnnotation(m)) {
                flags |= MI_NATIVE;
            }
        }
        if (Modifier.isAbstract(m.getModifiers())) {
            flags |= MI_ABSTRACT;
        }
        if (Modifier.isStrictFP(m.getModifiers())) {
            flags |= MI_STRICT;
        }
        if ((m.getModifiers() & 0x1000) > 0) {
            flags |= MI_SYNTHETIC;
        }
        if (attributesEncoder.methodHasAttributes(m)) {
            flags |= MI_ATTRIBUTES;
        }
        if (hasBridgeAnnotation(m) || hasGlobalValueAnnotation(m)) {
            flags |= MI_BRO_BRIDGE;
        }
        if (hasCallbackAnnotation(m)) {
            flags |= MI_BRO_CALLBACK;
        }
        if ((t instanceof PrimType || t == VoidType.v()) && m.getParameterCount() == 0) {
            flags |= MI_COMPACT_DESC;
        }
        body.add(new IntegerConstant((short) flags));
        Constant viTableIndex = new IntegerConstant((short) -1);
        if (vtable != null) {
            VTable.Entry entry = vtable.getEntry(m);
            if (entry != null) {
                viTableIndex = new IntegerConstant((short) entry.getIndex());
            }
        } else {
            ITable.Entry entry = itable.getEntry(m);
            if (entry != null) {
                viTableIndex = new IntegerConstant((short) entry.getIndex());
            }
        }
        body.add(viTableIndex);
        body.add(getString(m.getName()));
        if ((flags & MI_COMPACT_DESC) > 0) {
            int desc = 0;
            if (t.equals(BooleanType.v())) {
                desc = DESC_Z;
            } else if (t.equals(ByteType.v())) {
                desc = DESC_B;
            } else if (t.equals(ShortType.v())) {
                desc = DESC_S;
            } else if (t.equals(CharType.v())) {
                desc = DESC_C;
            } else if (t.equals(IntType.v())) {
                desc = DESC_I;
            } else if (t.equals(LongType.v())) {
                desc = DESC_J;
            } else if (t.equals(FloatType.v())) {
                desc = DESC_F;
            } else if (t.equals(DoubleType.v())) {
                desc = DESC_D;
            } else if (t.equals(VoidType.v())) {
                desc = DESC_V;
            }
            body.add(new IntegerConstant((byte) desc));
        } else {
            body.add(getString(getDescriptor(m)));
        }
        if (attributesEncoder.methodHasAttributes(m)) {
            body.add(new ConstantBitcast(attributesEncoder.getMethodAttributes(m).ref(), I8_PTR));
        }
        if (!m.isAbstract()) {
            body.add(new ConstantBitcast(new FunctionRef(Symbols.methodSymbol(m), getFunctionType(m)), I8_PTR));
            // Size of function. This value will be modified later by patching the .s file.
            body.add(new IntegerConstant(DUMMY_METHOD_SIZE));
            if (m.isSynchronized()) {
                body.add(new ConstantBitcast(new FunctionRef(Symbols.synchronizedWrapperSymbol(m), getFunctionType(m)), I8_PTR));
            }
            if ((flags & MI_NATIVE) == 0) {
                // Cannot use m.isNative() in the condition above since methods which are native in the
                // Java class file may have been changed to non-native by the RoboVM compiler 
                // (e.g. @StructMember methods). The native code which parses the info structs will see 
                // the method as non-native.
                // Add a weak linetable pointer which points to a -1 value which will be interpreted as 0 linenumbers in the table
                Global linetableGlobal = new Global(Symbols.linetableSymbol(m), Linkage.weak, new IntegerConstant(-1));
                mb.addGlobal(linetableGlobal);
                body.add(linetableGlobal.ref());
            }
        }
        if (hasBridgeAnnotation(m)) {
            if (!readBooleanElem(getAnnotation(m, BRIDGE), "dynamic", false)) {
                body.add(new GlobalRef(Symbols.bridgePtrSymbol(m), I8_PTR));
            } else {
                body.add(new NullConstant(I8_PTR));
            }
        } else if (hasGlobalValueAnnotation(m)) {
            body.add(new GlobalRef(Symbols.globalValuePtrSymbol(m), I8_PTR));
        }
        if (hasCallbackAnnotation(m)) {
            body.add(new AliasRef(Symbols.callbackPtrSymbol(m), I8_PTR));
        }
    }
    // after sizeof(ClassInfoHeader) bytes.
    return new StructureConstantBuilder().add(header.build()).add(body.build()).build();
}
Also used : GlobalRef(org.robovm.compiler.llvm.GlobalRef) PackedStructureConstantBuilder(org.robovm.compiler.llvm.PackedStructureConstantBuilder) AliasRef(org.robovm.compiler.llvm.AliasRef) StructureConstant(org.robovm.compiler.llvm.StructureConstant) Constant(org.robovm.compiler.llvm.Constant) NullConstant(org.robovm.compiler.llvm.NullConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) NullConstant(org.robovm.compiler.llvm.NullConstant) SootClass(soot.SootClass) StructureConstantBuilder(org.robovm.compiler.llvm.StructureConstantBuilder) PackedStructureConstantBuilder(org.robovm.compiler.llvm.PackedStructureConstantBuilder) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Global(org.robovm.compiler.llvm.Global) SootMethod(soot.SootMethod) PrimType(soot.PrimType) SootField(soot.SootField) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 22 with PrimType

use of soot.PrimType in project robovm by robovm.

the class BroMethodCompiler method getStructMemberType.

public Type getStructMemberType(SootMethod method) {
    String methodType = hasStructMemberAnnotation(method) ? "@StructMember" : "@GlobalValue";
    SootMethod getter = method.getParameterCount() == 0 ? method : null;
    SootMethod setter = getter == null ? method : null;
    soot.Type type = getter != null ? getter.getReturnType() : setter.getParameterType(0);
    Type memberType = null;
    if (getter != null && hasPointerAnnotation(getter) || setter != null && hasPointerAnnotation(setter, 0)) {
        memberType = I8_PTR;
    } else if (getter != null && hasMachineSizedFloatAnnotation(getter) || setter != null && hasMachineSizedFloatAnnotation(setter, 0)) {
        memberType = config.getArch().is32Bit() ? FLOAT : DOUBLE;
    } else if (getter != null && (hasMachineSizedSIntAnnotation(getter) || hasMachineSizedUIntAnnotation(getter)) || setter != null && (hasMachineSizedSIntAnnotation(setter, 0) || hasMachineSizedUIntAnnotation(setter, 0))) {
        memberType = config.getArch().is32Bit() ? I32 : I64;
    } else if (type instanceof PrimType) {
        memberType = getType(type);
    } else if (getter != null && hasArrayAnnotation(getter) || setter != null && hasArrayAnnotation(setter, 0)) {
        int[] dimensions = getter != null ? getArrayDimensions(getter) : getArrayDimensions(setter, 0);
        if (dimensions == null || dimensions.length == 0) {
            throw new IllegalArgumentException("No dimensions specified for @Array annotation on " + methodType + " " + (getter != null ? "getter" : "setter") + " " + method);
        }
        if (type instanceof soot.ArrayType && ((soot.ArrayType) type).numDimensions != dimensions.length) {
            throw new IllegalArgumentException("Mismatch in number of dimennsions for @Array annotation " + "and type on " + methodType + " " + (getter != null ? "getter" : "setter") + " " + method);
        }
        Type baseType = null;
        if (type instanceof soot.ArrayType) {
            soot.ArrayType arrayType = (soot.ArrayType) type;
            if (isStruct(arrayType.baseType)) {
                // ByVal is implied for arrays of structs
                try {
                    baseType = getStructType(arrayType.baseType);
                } catch (StackOverflowError e) {
                    throw new IllegalArgumentException("Struct type " + type + " refers to itself");
                }
            } else {
                baseType = getType(arrayType.baseType);
            }
        } else if (isStruct(type)) {
            // ByVal is implied
            try {
                baseType = getStructType(type);
            } catch (StackOverflowError e) {
                throw new IllegalArgumentException("Struct type " + type + " refers to itself");
            }
        } else if (type instanceof RefType) {
            MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(getter != null ? new MarshalSite(getter) : new MarshalSite(setter, 0));
            baseType = getType(((ArrayMarshalerMethod) marshalerMethod).getBaseType());
        }
        if (baseType == null) {
            throw new IllegalArgumentException("Arrays of " + type + " is not supported");
        }
        long total = dimensions[0];
        for (int i = 1; i < dimensions.length; i++) {
            total *= dimensions[i];
        }
        memberType = new ArrayType(total, baseType);
    } else if (isStruct(type)) {
        boolean byVal = getter != null ? isPassByValue(getter) : isPassByValue(setter, 0);
        if (!byVal) {
            // NOTE: We use i8* instead of <StructType>* to support pointers to recursive structs
            memberType = I8_PTR;
        } else {
            try {
                memberType = getStructType(type);
            } catch (StackOverflowError e) {
                throw new IllegalArgumentException("Struct type " + type + " refers to itself");
            }
        }
    } else if (isNativeObject(type)) {
        memberType = I8_PTR;
    } else {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(getter != null ? new MarshalSite(getter) : new MarshalSite(setter, 0));
        if (marshalerMethod instanceof ValueMarshalerMethod) {
            memberType = ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
        } else {
            memberType = I8_PTR;
        }
    }
    return memberType;
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) Ptrtoint(org.robovm.compiler.llvm.Ptrtoint) ArrayType(org.robovm.compiler.llvm.ArrayType) RefType(soot.RefType) RefType(soot.RefType) IntegerType(org.robovm.compiler.llvm.IntegerType) StructureType(org.robovm.compiler.llvm.StructureType) ArrayType(org.robovm.compiler.llvm.ArrayType) PointerType(org.robovm.compiler.llvm.PointerType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) LongType(soot.LongType) Type(org.robovm.compiler.llvm.Type) AggregateType(org.robovm.compiler.llvm.AggregateType) PrimitiveType(org.robovm.compiler.llvm.PrimitiveType) PrimType(soot.PrimType) VoidType(soot.VoidType) FunctionType(org.robovm.compiler.llvm.FunctionType) SootMethod(soot.SootMethod) PrimType(soot.PrimType) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)

Example 23 with PrimType

use of soot.PrimType in project robovm by robovm.

the class BroMethodCompiler method getParameterType.

private Type getParameterType(String anno, SootMethod method, int i) {
    soot.Type sootType = method.getParameterType(i);
    if (hasPointerAnnotation(method, i)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type long when annotated with @Pointer.");
        }
        return I8_PTR;
    }
    if (hasMachineSizedFloatAnnotation(method, i)) {
        if (!sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
            throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type float or double when annotated with @MachineSizedFloat.");
        }
        return config.getArch().is32Bit() ? FLOAT : DOUBLE;
    }
    if (hasMachineSizedSIntAnnotation(method, i) || hasMachineSizedUIntAnnotation(method, i)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type long when annotated with " + "@MachineSizedSInt or @MachineSizedUInt");
        }
        return config.getArch().is32Bit() ? I32 : I64;
    }
    if (hasStructRetAnnotation(method, i)) {
        if (i > 0) {
            throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " cannot be annotated with @StructRet. Only the first" + " parameter may have this annotation.");
        }
        if (!isStruct(sootType)) {
            throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be a sub class of Struct when annotated with @StructRet.");
        }
        // @StructRet implies pass by reference
        return new PointerType(getStructType(sootType));
    }
    if (isStruct(sootType)) {
        StructureType structType = getStructType(sootType);
        if (hasByValAnnotation(method, i)) {
            return getStructType(sootType);
        }
        return new PointerType(structType);
    } else if (isNativeObject(sootType)) {
        // NativeObjects are always passed by reference.
        return I8_PTR;
    } else if (sootType instanceof PrimType) {
        return getType(sootType);
    }
    MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, i));
    if (marshalerMethod instanceof ValueMarshalerMethod) {
        return ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
    } else {
        return I8_PTR;
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) StructureType(org.robovm.compiler.llvm.StructureType) PrimType(soot.PrimType) PointerType(org.robovm.compiler.llvm.PointerType) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)

Example 24 with PrimType

use of soot.PrimType in project soot by Sable.

the class IFDSPossibleTypes method createFlowFunctionsFactory.

public FlowFunctions<Unit, Pair<Value, Type>, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Pair<Value, Type>, SootMethod>() {

        public FlowFunction<Pair<Value, Type>> getNormalFlowFunction(Unit src, Unit dest) {
            if (src instanceof DefinitionStmt) {
                DefinitionStmt defnStmt = (DefinitionStmt) src;
                if (defnStmt.containsInvokeExpr())
                    return Identity.v();
                final Value right = defnStmt.getRightOp();
                final Value left = defnStmt.getLeftOp();
                // won't track primitive-typed variables
                if (right.getType() instanceof PrimType)
                    return Identity.v();
                if (right instanceof Constant || right instanceof NewExpr) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                            if (source == zeroValue()) {
                                Set<Pair<Value, Type>> res = new LinkedHashSet<Pair<Value, Type>>();
                                res.add(new Pair<Value, Type>(left, right.getType()));
                                res.add(zeroValue());
                                return res;
                            } else if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else {
                                return Collections.singleton(source);
                            }
                        }
                    };
                } else if (right instanceof Ref || right instanceof Local) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(final Pair<Value, Type> source) {
                            Value value = source.getO1();
                            if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else if (maybeSameLocation(value, right)) {
                                return new LinkedHashSet<Pair<Value, Type>>() {

                                    {
                                        add(new Pair<Value, Type>(left, source.getO2()));
                                        add(source);
                                    }
                                };
                            } else {
                                return Collections.singleton(source);
                            }
                        }

                        private boolean maybeSameLocation(Value v1, Value v2) {
                            if (!(v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) && !(v1 instanceof ArrayRef && v2 instanceof ArrayRef)) {
                                return v1.equivTo(v2);
                            }
                            if (v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) {
                                InstanceFieldRef ifr1 = (InstanceFieldRef) v1;
                                InstanceFieldRef ifr2 = (InstanceFieldRef) v2;
                                if (!ifr1.getField().getName().equals(ifr2.getField().getName()))
                                    return false;
                                Local base1 = (Local) ifr1.getBase();
                                Local base2 = (Local) ifr2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            } else {
                                // v1 instanceof ArrayRef && v2 instanceof ArrayRef
                                ArrayRef ar1 = (ArrayRef) v1;
                                ArrayRef ar2 = (ArrayRef) v2;
                                Local base1 = (Local) ar1.getBase();
                                Local base2 = (Local) ar2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            }
                        }
                    };
                }
            }
            return Identity.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallFlowFunction(final Unit src, final SootMethod dest) {
            Stmt stmt = (Stmt) src;
            InvokeExpr ie = stmt.getInvokeExpr();
            final List<Value> callArgs = ie.getArgs();
            final List<Local> paramLocals = new ArrayList<Local>();
            for (int i = 0; i < dest.getParameterCount(); i++) {
                paramLocals.add(dest.getActiveBody().getParameterLocal(i));
            }
            return new FlowFunction<Pair<Value, Type>>() {

                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                    if (!dest.getName().equals("<clinit>") && !dest.getSubSignature().equals("void run()")) {
                        Value value = source.getO1();
                        int argIndex = callArgs.indexOf(value);
                        if (argIndex > -1) {
                            return Collections.singleton(new Pair<Value, Type>(paramLocals.get(argIndex), source.getO2()));
                        }
                    }
                    return Collections.emptySet();
                }
            };
        }

        public FlowFunction<Pair<Value, Type>> getReturnFlowFunction(Unit callSite, SootMethod callee, Unit exitStmt, Unit retSite) {
            if (exitStmt instanceof ReturnStmt) {
                ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                Value op = returnStmt.getOp();
                if (op instanceof Local) {
                    if (callSite instanceof DefinitionStmt) {
                        DefinitionStmt defnStmt = (DefinitionStmt) callSite;
                        Value leftOp = defnStmt.getLeftOp();
                        if (leftOp instanceof Local) {
                            final Local tgtLocal = (Local) leftOp;
                            final Local retLocal = (Local) op;
                            return new FlowFunction<Pair<Value, Type>>() {

                                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                                    if (source == retLocal)
                                        return Collections.singleton(new Pair<Value, Type>(tgtLocal, source.getO2()));
                                    return Collections.emptySet();
                                }
                            };
                        }
                    }
                }
            }
            return KillAll.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
            return Identity.v();
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PointsToSet(soot.PointsToSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Constant(soot.jimple.Constant) ArrayList(java.util.ArrayList) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) PrimType(soot.PrimType) PointsToAnalysis(soot.PointsToAnalysis) Pair(soot.toolkits.scalar.Pair) PointsToSet(soot.PointsToSet) FlowFunction(heros.FlowFunction) Local(soot.Local) UnknownType(soot.UnknownType) Type(soot.Type) PrimType(soot.PrimType) ArrayRef(soot.jimple.ArrayRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) Value(soot.Value) NewExpr(soot.jimple.NewExpr) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt)

Example 25 with PrimType

use of soot.PrimType in project soot by Sable.

the class ReflectiveCallsInliner method insertCastOrBoxingCode.

private void insertCastOrBoxingCode(Local lhs, Local rhs, Chain<Unit> newUnits) {
    // if assigning to a primitive type then there's nothing to do
    if (lhs.getType() instanceof RefLikeType) {
        if ((rhs.getType() instanceof RefLikeType)) {
            // insert cast
            newUnits.add(Jimple.v().newAssignStmt(lhs, Jimple.v().newCastExpr(rhs, lhs.getType())));
        } else {
            // primitive type in rhs; insert boxing code
            RefType boxedType = ((PrimType) rhs.getType()).boxedType();
            SootMethodRef ref = Scene.v().makeMethodRef(boxedType.getSootClass(), "valueOf", Collections.<Type>singletonList(rhs.getType()), boxedType, true);
            newUnits.add(Jimple.v().newAssignStmt(lhs, Jimple.v().newStaticInvokeExpr(ref, rhs)));
        }
    }
}
Also used : RefLikeType(soot.RefLikeType) RefType(soot.RefType) SootMethodRef(soot.SootMethodRef) PrimType(soot.PrimType)

Aggregations

PrimType (soot.PrimType)31 RefType (soot.RefType)15 ArrayList (java.util.ArrayList)12 Type (soot.Type)10 Value (soot.Value)10 DoubleType (soot.DoubleType)9 FloatType (soot.FloatType)9 IntType (soot.IntType)9 Local (soot.Local)9 LongType (soot.LongType)9 BooleanType (soot.BooleanType)8 SootClass (soot.SootClass)8 SootMethod (soot.SootMethod)8 ByteType (soot.ByteType)7 CharType (soot.CharType)7 ShortType (soot.ShortType)7 ArrayType (soot.ArrayType)6 VoidType (soot.VoidType)6 MethodVisitor (org.objectweb.asm.MethodVisitor)4 PointerType (org.robovm.compiler.llvm.PointerType)4