Search in sources :

Example 21 with StructureType

use of org.robovm.compiler.llvm.StructureType in project robovm by robovm.

the class BroMethodCompiler method loadValueForGetter.

protected Value loadValueForGetter(SootMethod method, Function fn, Type memberType, Value memberPtr, Value env, boolean dereference, long flags) {
    soot.Type type = method.getReturnType();
    Value result = null;
    if (memberType instanceof StructureType) {
        // The member is a child struct contained in the current struct
        result = memberPtr;
    } else if (memberType instanceof ArrayType) {
        // The member is an array contained in the current struct
        result = memberPtr;
    } else if (dereference) {
        Variable tmp = fn.newVariable(memberType);
        fn.add(new Load(tmp, memberPtr));
        result = tmp.ref();
    } else {
        // Do not dereference the pointer but use it as is. This is needed for
        // global values such as _dispatch_main_q which is a struct and not a
        // pointer which we should load. We want the address of the struct.
        Variable tmp = fn.newVariable(memberType);
        fn.add(new Bitcast(tmp, memberPtr, tmp.getType()));
        result = tmp.ref();
    }
    if (needsMarshaler(type)) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
        String targetClassName = getInternalName(type);
        if (memberType instanceof PrimitiveType) {
            // Value type wrapping a primitive value (e.g. Enum, Integer and Bits)
            result = marshalNativeToValueObject(fn, marshalerMethod, env, targetClassName, result, flags);
        } else {
            if (memberType instanceof ArrayType) {
                // Array
                result = marshalNativeToArray(fn, marshalerMethod, env, targetClassName, result, flags, getArrayDimensions(method));
            } else {
                result = marshalNativeToObject(fn, marshalerMethod, null, env, targetClassName, result, flags);
            }
        }
    } else {
        result = marshalNativeToPrimitive(fn, method, result);
    }
    return result;
}
Also used : ArrayType(org.robovm.compiler.llvm.ArrayType) MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) Load(org.robovm.compiler.llvm.Load) Variable(org.robovm.compiler.llvm.Variable) Bitcast(org.robovm.compiler.llvm.Bitcast) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) StructureType(org.robovm.compiler.llvm.StructureType) Value(org.robovm.compiler.llvm.Value) PrimitiveType(org.robovm.compiler.llvm.PrimitiveType) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)

Example 22 with StructureType

use of org.robovm.compiler.llvm.StructureType 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 23 with StructureType

use of org.robovm.compiler.llvm.StructureType in project robovm by robovm.

the class BroMethodCompiler method getStructType.

private StructureType getStructType(SootClass clazz, boolean checkEmpty) {
    int n = 0;
    for (SootMethod method : clazz.getMethods()) {
        n = Math.max(getStructMemberOffset(method) + 1, n);
    }
    Type[] result = new Type[n + 1];
    StructureType superType = null;
    if (clazz.hasSuperclass()) {
        SootClass superclass = clazz.getSuperclass();
        if (!superclass.getName().equals("org.robovm.rt.bro.Struct")) {
            superType = getStructType(superclass, false);
        }
    }
    result[0] = superType != null ? superType : new StructureType();
    for (SootMethod method : clazz.getMethods()) {
        int offset = getStructMemberOffset(method);
        if (offset != -1) {
            if (!method.isNative() && !method.isStatic()) {
                throw new IllegalArgumentException("@StructMember annotated method " + method + " must be native and not static");
            }
            Type type = null;
            if (method.getParameterCount() == 0) {
                soot.Type sootType = method.getReturnType();
                // Possibly a getter
                if (hasPointerAnnotation(method) && !sootType.equals(LongType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated getter " + method + " must be of type long when annotated with @Pointer");
                }
                if (hasMachineSizedFloatAnnotation(method) && !sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated getter " + method + " must be of type float or double when annotated with @MachineSizedFloat");
                }
                if ((hasMachineSizedSIntAnnotation(method) || hasMachineSizedUIntAnnotation(method)) && !sootType.equals(LongType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated getter " + method + " must be of type long when annotated with @MachineSizedSInt or @MachineSizedUInt");
                }
                if (sootType instanceof soot.ArrayType && !hasArrayAnnotation(method)) {
                    throw new IllegalArgumentException("@Array annotation expected on struct member getter " + method);
                }
            } else if (method.getParameterCount() == 1) {
                soot.Type sootType = method.getParameterType(0);
                if (hasPointerAnnotation(method, 0) && !sootType.equals(LongType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated setter " + method + " must be of type long when annotated with @Pointer");
                }
                if (hasMachineSizedFloatAnnotation(method, 0) && !sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated setter " + method + " must be of type float or double when annotated with @MachineSizedFloat");
                }
                if ((hasMachineSizedSIntAnnotation(method, 0) || hasMachineSizedUIntAnnotation(method)) && !sootType.equals(LongType.v())) {
                    throw new IllegalArgumentException("@StructMember(" + offset + ") annotated setter " + method + " must be of type long when annotated with @MachineSizedSInt or @MachineSizedUInt");
                }
                if (sootType instanceof soot.ArrayType && !hasArrayAnnotation(method, 0)) {
                    throw new IllegalArgumentException("@Array annotation expected on first parameter of struct member setter " + method);
                }
                soot.Type retType = method.getReturnType();
                // The return type of the setter must be void or this
                if (!retType.equals(VoidType.v()) && !(retType instanceof RefType && ((RefType) retType).getSootClass().equals(clazz))) {
                    throw new IllegalArgumentException("Setter " + method + " for " + "@StructMember(" + offset + ") " + " must either return nothing or return a " + clazz);
                }
            } else {
                throw new IllegalArgumentException("@StructMember annotated method " + method + " has too many parameters");
            }
            type = getStructMemberType(method);
            int index = offset + 1;
            if (result[index] == null) {
                result[index] = type;
            } else if (type != result[index]) {
                // Two members mapped to the same offset (union). Pick
                // the type with the largest alignment and pad with bytes
                // up to the largest size.
                result[index] = mergeStructMemberTypes(config.getDataLayout(), type, result[index]);
            }
        }
    }
    for (int i = 1; i < result.length; i++) {
        if (result[i] == null) {
            throw new IllegalArgumentException("No @StructMember(" + i + ") defined in class " + clazz);
        }
    }
    if (!clazz.isAbstract() && checkEmpty && n == 0 && superType == null) {
        throw new IllegalArgumentException("Struct class " + clazz + " has no @StructMember annotated methods");
    }
    return new StructureType(result);
}
Also used : 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) StructureType(org.robovm.compiler.llvm.StructureType) SootMethod(soot.SootMethod) SootClass(soot.SootClass) Ptrtoint(org.robovm.compiler.llvm.Ptrtoint)

Example 24 with StructureType

use of org.robovm.compiler.llvm.StructureType in project robovm by robovm.

the class BroMethodCompiler method storeValueForSetter.

protected void storeValueForSetter(SootMethod method, Function function, Type memberType, Value memberPtr, Value env, Value value, long flags) {
    soot.Type type = method.getParameterType(0);
    if (needsMarshaler(type)) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, 0));
        if (memberType instanceof PrimitiveType) {
            value = marshalValueObjectToNative(function, marshalerMethod, memberType, env, value, flags);
        } else {
            if (memberType instanceof StructureType || memberType instanceof ArrayType) {
                // The parameter must not be null. We assume that Structs 
                // never have a NULL handle so we just check that the Java
                // Object isn't null.
                call(function, CHECK_NULL, env, value);
            }
            if (memberType instanceof ArrayType) {
                // Array
                marshalArrayToNative(function, marshalerMethod, env, value, memberPtr, flags, getArrayDimensions(method, 0));
                value = null;
            } else {
                value = marshalObjectToNative(function, marshalerMethod, null, memberType, env, value, flags);
            }
        }
    } else {
        value = marshalPrimitiveToNative(function, method, 0, value);
    }
    if (value != null) {
        function.add(new Store(value, memberPtr));
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) ArrayType(org.robovm.compiler.llvm.ArrayType) StructureType(org.robovm.compiler.llvm.StructureType) Store(org.robovm.compiler.llvm.Store) PrimitiveType(org.robovm.compiler.llvm.PrimitiveType) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)

Example 25 with StructureType

use of org.robovm.compiler.llvm.StructureType in project robovm by robovm.

the class BroMethodCompiler method marshalNativeToObject.

protected Value marshalNativeToObject(Function fn, MarshalerMethod marshalerMethod, MarshaledArg marshaledArg, Value env, String valueClassName, Value nativeValue, long flags) {
    if (nativeValue.getType() instanceof StructureType) {
        nativeValue = createStackCopy(fn, nativeValue);
    }
    Invokestatic invokestatic = marshalerMethod.getInvokeStatic(sootMethod.getDeclaringClass());
    trampolines.add(invokestatic);
    Value valueClass = ldcClass(fn, valueClassName, env);
    Variable handle = fn.newVariable(I64);
    fn.add(new Ptrtoint(handle, nativeValue, I64));
    Value object = call(fn, invokestatic.getFunctionRef(), env, valueClass, handle.ref(), new IntegerConstant(flags));
    if (marshaledArg != null) {
        marshaledArg.handle = handle.ref();
        marshaledArg.object = object;
    }
    return object;
}
Also used : Invokestatic(org.robovm.compiler.trampoline.Invokestatic) Variable(org.robovm.compiler.llvm.Variable) Ptrtoint(org.robovm.compiler.llvm.Ptrtoint) StructureType(org.robovm.compiler.llvm.StructureType) Value(org.robovm.compiler.llvm.Value) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Aggregations

StructureType (org.robovm.compiler.llvm.StructureType)25 FunctionType (org.robovm.compiler.llvm.FunctionType)16 PointerType (org.robovm.compiler.llvm.PointerType)14 Test (org.junit.Test)10 ArrayType (org.robovm.compiler.llvm.ArrayType)8 PrimitiveType (org.robovm.compiler.llvm.PrimitiveType)8 Type (org.robovm.compiler.llvm.Type)8 Value (org.robovm.compiler.llvm.Value)7 Variable (org.robovm.compiler.llvm.Variable)6 LongType (soot.LongType)6 MarshalSite (org.robovm.compiler.MarshalerLookup.MarshalSite)5 MarshalerMethod (org.robovm.compiler.MarshalerLookup.MarshalerMethod)5 Function (org.robovm.compiler.llvm.Function)5 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)5 Load (org.robovm.compiler.llvm.Load)5 ArrayList (java.util.ArrayList)4 AggregateType (org.robovm.compiler.llvm.AggregateType)4 Bitcast (org.robovm.compiler.llvm.Bitcast)4 IntegerType (org.robovm.compiler.llvm.IntegerType)4 Ptrtoint (org.robovm.compiler.llvm.Ptrtoint)4