Search in sources :

Example 1 with ArrayMarshalerMethod

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

ArrayMarshalerMethod (org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)1 MarshalSite (org.robovm.compiler.MarshalerLookup.MarshalSite)1 MarshalerMethod (org.robovm.compiler.MarshalerLookup.MarshalerMethod)1 ValueMarshalerMethod (org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod)1 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 PointerType (org.robovm.compiler.llvm.PointerType)1 PrimitiveType (org.robovm.compiler.llvm.PrimitiveType)1 Ptrtoint (org.robovm.compiler.llvm.Ptrtoint)1 StructureType (org.robovm.compiler.llvm.StructureType)1 Type (org.robovm.compiler.llvm.Type)1 DoubleType (soot.DoubleType)1 FloatType (soot.FloatType)1 LongType (soot.LongType)1 PrimType (soot.PrimType)1 RefType (soot.RefType)1 SootMethod (soot.SootMethod)1 VoidType (soot.VoidType)1