Search in sources :

Example 1 with RefType

use of soot.RefType in project robovm by robovm.

the class MarshalerLookup method getBaseType.

private soot.Type getBaseType(SootMethod m, AnnotationTag anno) {
    AnnotationClassElem el = (AnnotationClassElem) getElemByName(anno, "baseType");
    if (el != null) {
        switch(el.getDesc().charAt(0)) {
            case 'Z':
                return BooleanType.v();
            case 'B':
                return ByteType.v();
            case 'S':
                return ShortType.v();
            case 'C':
                return CharType.v();
            case 'I':
                return IntType.v();
            case 'J':
                return LongType.v();
            case 'F':
                return FloatType.v();
            case 'D':
                return DoubleType.v();
        }
        return null;
    }
    soot.Type t = m.getReturnType();
    if (t == VoidType.v()) {
        t = m.getParameterType(0);
    }
    if (t instanceof RefType) {
        SootClass c = ((RefType) t).getSootClass();
        if (isInstanceOfClass(c, "java.nio.ByteBuffer")) {
            return ByteType.v();
        } else if (isInstanceOfClass(c, "java.nio.ShortBuffer")) {
            return ShortType.v();
        } else if (isInstanceOfClass(c, "java.nio.CharBuffer")) {
            return CharType.v();
        } else if (isInstanceOfClass(c, "java.nio.IntBuffer")) {
            return IntType.v();
        } else if (isInstanceOfClass(c, "java.nio.LongBuffer")) {
            return LongType.v();
        } else if (isInstanceOfClass(c, "java.nio.FloatBuffer")) {
            return FloatType.v();
        } else if (isInstanceOfClass(c, "java.nio.DoubleBuffer")) {
            return DoubleType.v();
        } else if (isInstanceOfClass(c, "org.robovm.rt.bro.Struct")) {
            return config.getClazzes().load("org/robovm/rt/bro/Struct").getSootClass().getType();
        }
    } else if (t instanceof ArrayType) {
        ArrayType arrayType = (ArrayType) t;
        if (arrayType.baseType instanceof PrimType || isInstanceOfClass(arrayType.baseType, "org.robovm.rt.bro.Struct")) {
            return arrayType.baseType;
        }
    }
    return null;
}
Also used : RefType(soot.RefType) ArrayType(soot.ArrayType) AnnotationClassElem(soot.tagkit.AnnotationClassElem) PrimType(soot.PrimType) SootClass(soot.SootClass)

Example 2 with RefType

use of soot.RefType in project robovm by robovm.

the class ObjCBlockPlugin method getBlockTargetMethod.

protected static SootMethod getBlockTargetMethod(SootMethod method) {
    soot.Type type = method.getReturnType();
    if (!(type instanceof RefType)) {
        throw new CompilerException("@Block annotated return type of method " + method + " must be of interface type");
    }
    SootClass blockType = ((RefType) type).getSootClass();
    if (!blockType.isInterface()) {
        throw new CompilerException("@Block annotated parameter return type " + "of method " + method + " must be of interface type");
    }
    List<SootMethod> allMethods = collectAbstractMethods(blockType);
    if (allMethods.isEmpty()) {
        throw new CompilerException("No abstract method found in interface " + blockType + " used in @Block annotated return type of method " + method);
    }
    if (allMethods.size() > 1) {
        throw new CompilerException("More than 1 abstract method found in interface " + blockType + " used in @Block annotated return type of method " + method);
    }
    return allMethods.get(0);
}
Also used : RefType(soot.RefType) CompilerException(org.robovm.compiler.CompilerException) SootMethod(soot.SootMethod) SootClass(soot.SootClass)

Example 3 with RefType

use of soot.RefType in project robovm by robovm.

the class ObjCMemberPlugin method createCallback.

private void createCallback(SootClass sootClass, SootMethod method, SootMethod annotatedMethod, String selectorName, Type receiverType) {
    Jimple j = Jimple.v();
    SootMethod callbackMethod = getCallbackMethod(selectorName, method, annotatedMethod, receiverType);
    sootClass.addMethod(callbackMethod);
    addCallbackAnnotation(callbackMethod);
    addBindSelectorAnnotation(callbackMethod, selectorName);
    if (!hasAnnotation(annotatedMethod, TYPE_ENCODING) && (isCustomClass(sootClass) || ObjCProtocolProxyPlugin.isObjCProxy(sootClass))) {
        String encoding = generateTypeEncoding(callbackMethod);
        try {
            addTypeEncodingAnnotation(callbackMethod, encoding);
        } catch (IllegalArgumentException e) {
            throw new CompilerException("Failed to determine method type encoding for method " + method + ": " + e.getMessage());
        }
    }
    Body body = j.newBody(callbackMethod);
    callbackMethod.setActiveBody(body);
    PatchingChain<Unit> units = body.getUnits();
    Local thiz = null;
    if (!method.isStatic()) {
        thiz = j.newLocal("$this", receiverType);
        body.getLocals().add(thiz);
        units.add(j.newIdentityStmt(thiz, j.newParameterRef(receiverType, 0)));
    }
    LinkedList<Value> args = new LinkedList<>();
    for (int i = 0; i < method.getParameterCount(); i++) {
        Type t = method.getParameterType(i);
        Local p = j.newLocal("$p" + i, t);
        body.getLocals().add(p);
        units.add(j.newIdentityStmt(p, j.newParameterRef(t, i + 2)));
        args.add(p);
    }
    Local ret = null;
    if (method.getReturnType() != VoidType.v()) {
        ret = j.newLocal("$ret", method.getReturnType());
        body.getLocals().add(ret);
    }
    SootMethodRef targetMethod = method.makeRef();
    if (((RefType) receiverType).getSootClass().isInterface()) {
        @SuppressWarnings("unchecked") List<Type> parameterTypes = method.getParameterTypes();
        targetMethod = Scene.v().makeMethodRef(((RefType) receiverType).getSootClass(), method.getName(), parameterTypes, method.getReturnType(), false);
    }
    InvokeExpr expr = method.isStatic() ? j.newStaticInvokeExpr(targetMethod, args) : (((RefType) receiverType).getSootClass().isInterface() ? j.newInterfaceInvokeExpr(thiz, targetMethod, args) : j.newVirtualInvokeExpr(thiz, targetMethod, args));
    units.add(ret == null ? j.newInvokeStmt(expr) : j.newAssignStmt(ret, expr));
    if (ret != null) {
        units.add(j.newReturnStmt(ret));
    } else {
        units.add(j.newReturnVoidStmt());
    }
}
Also used : SootMethodRef(soot.SootMethodRef) Local(soot.Local) Unit(soot.Unit) LinkedList(java.util.LinkedList) RefType(soot.RefType) 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) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Value(soot.Value) SootMethod(soot.SootMethod) CompilerException(org.robovm.compiler.CompilerException) Jimple(soot.jimple.Jimple) Body(soot.Body)

Example 4 with RefType

use of soot.RefType in project robovm by robovm.

the class ObjCBlockPlugin method getBlockTargetMethod.

protected static SootMethod getBlockTargetMethod(SootMethod method, int paramIndex) {
    soot.Type type = method.getParameterType(paramIndex);
    if (!(type instanceof RefType)) {
        throw new CompilerException("@Block annotated parameter " + (paramIndex + 1) + " of method " + method + " must be of interface type");
    }
    SootClass blockType = ((RefType) type).getSootClass();
    if (!blockType.isInterface()) {
        throw new CompilerException("@Block annotated parameter " + (paramIndex + 1) + " of method " + method + " must be of interface type");
    }
    List<SootMethod> allMethods = collectAbstractMethods(blockType);
    if (allMethods.isEmpty()) {
        throw new CompilerException("No abstract method found in interface " + blockType + " used in @Block annotated parameter " + (paramIndex + 1) + " of method " + method);
    }
    if (allMethods.size() > 1) {
        throw new CompilerException("More than 1 abstract method found in interface " + blockType + " used in @Block annotated parameter " + (paramIndex + 1) + " of method " + method);
    }
    return allMethods.get(0);
}
Also used : RefType(soot.RefType) CompilerException(org.robovm.compiler.CompilerException) SootMethod(soot.SootMethod) SootClass(soot.SootClass)

Example 5 with RefType

use of soot.RefType 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)

Aggregations

RefType (soot.RefType)7 SootClass (soot.SootClass)5 SootMethod (soot.SootMethod)5 PrimType (soot.PrimType)4 CompilerException (org.robovm.compiler.CompilerException)3 DoubleType (soot.DoubleType)3 FloatType (soot.FloatType)3 LongType (soot.LongType)3 VoidType (soot.VoidType)3 AggregateType (org.robovm.compiler.llvm.AggregateType)2 ArrayType (org.robovm.compiler.llvm.ArrayType)2 FunctionType (org.robovm.compiler.llvm.FunctionType)2 IntegerType (org.robovm.compiler.llvm.IntegerType)2 PointerType (org.robovm.compiler.llvm.PointerType)2 PrimitiveType (org.robovm.compiler.llvm.PrimitiveType)2 Ptrtoint (org.robovm.compiler.llvm.Ptrtoint)2 StructureType (org.robovm.compiler.llvm.StructureType)2 Type (org.robovm.compiler.llvm.Type)2 ArrayType (soot.ArrayType)2 ArrayList (java.util.ArrayList)1