Search in sources :

Example 1 with ValueMarshalerMethod

use of org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod in project robovm by robovm.

the class BroMethodCompiler method getReturnType.

private Type getReturnType(String anno, SootMethod method) {
    soot.Type sootType = method.getReturnType();
    if (hasPointerAnnotation(method)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @Pointer");
        }
        return I8_PTR;
    }
    if (hasMachineSizedFloatAnnotation(method)) {
        if (!sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return float or double when annotated with @MachineSizedFloat");
        }
        return config.getArch().is32Bit() ? FLOAT : DOUBLE;
    }
    if (hasMachineSizedSIntAnnotation(method) || hasMachineSizedUIntAnnotation(method)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @MachineSizedSInt or @MachineSizedUInt");
        }
        return config.getArch().is32Bit() ? I32 : I64;
    }
    if (isStruct(sootType)) {
        if (!isPassByValue(method)) {
            // Structs are returned by reference by default
            return new PointerType(getStructType(sootType));
        }
        return getStructType(sootType);
    } else if (isNativeObject(sootType)) {
        // NativeObjects are always returned by reference.
        return I8_PTR;
    } else if (sootType instanceof PrimType || sootType == VoidType.v()) {
        return getType(sootType);
    }
    MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
    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) 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 2 with ValueMarshalerMethod

use of org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod 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 3 with ValueMarshalerMethod

use of org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod 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)

Aggregations

ArrayMarshalerMethod (org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)3 MarshalSite (org.robovm.compiler.MarshalerLookup.MarshalSite)3 MarshalerMethod (org.robovm.compiler.MarshalerLookup.MarshalerMethod)3 ValueMarshalerMethod (org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod)3 PointerType (org.robovm.compiler.llvm.PointerType)3 PrimType (soot.PrimType)3 StructureType (org.robovm.compiler.llvm.StructureType)2 AggregateType (org.robovm.compiler.llvm.AggregateType)1 ArrayType (org.robovm.compiler.llvm.ArrayType)1 FunctionType (org.robovm.compiler.llvm.FunctionType)1 IntegerType (org.robovm.compiler.llvm.IntegerType)1 PrimitiveType (org.robovm.compiler.llvm.PrimitiveType)1 Ptrtoint (org.robovm.compiler.llvm.Ptrtoint)1 Type (org.robovm.compiler.llvm.Type)1 DoubleType (soot.DoubleType)1 FloatType (soot.FloatType)1 LongType (soot.LongType)1 RefType (soot.RefType)1 SootMethod (soot.SootMethod)1 VoidType (soot.VoidType)1