Search in sources :

Example 21 with MarshalSite

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

the class MarshalerLookupTest method testFindMarshalerMethodUnsuccessfulSearchUnsupportedCallTypeCallback.

@Test
public void testFindMarshalerMethodUnsuccessfulSearchUnsupportedCallTypeCallback() {
    MarshalerLookup lookup = new MarshalerLookup(config).searchBuiltins(false);
    SootMethod method = toSootClass(Foo4.class).getMethodByName("foo5");
    try {
        lookup.findMarshalerMethod(new MarshalSite(method)).getMethod();
        fail("IllegalArgumentException expected");
    } catch (IllegalArgumentException e) {
    }
    try {
        lookup.findMarshalerMethod(new MarshalSite(method, 0)).getMethod();
        fail("IllegalArgumentException expected");
    } catch (IllegalArgumentException e) {
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) SootMethod(soot.SootMethod) Test(org.junit.Test)

Example 22 with MarshalSite

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

the class BridgeMethodCompiler method updateObject.

private void updateObject(SootMethod method, Function fn, Value env, long flags, List<MarshaledArg> marshaledArgs) {
    for (MarshaledArg value : marshaledArgs) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, value.paramIndex));
        SootMethod afterMethod = ((PointerMarshalerMethod) marshalerMethod).getAfterBridgeCallMethod();
        if (afterMethod != null) {
            Invokestatic invokestatic = new Invokestatic(getInternalName(method.getDeclaringClass()), getInternalName(afterMethod.getDeclaringClass()), afterMethod.getName(), getDescriptor(afterMethod));
            trampolines.add(invokestatic);
            call(fn, invokestatic.getFunctionRef(), env, value.object, value.handle, new IntegerConstant(flags));
        }
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) Invokestatic(org.robovm.compiler.trampoline.Invokestatic) PointerMarshalerMethod(org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod) SootMethod(soot.SootMethod) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) PointerMarshalerMethod(org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Example 23 with MarshalSite

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

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

the class CallbackMethodCompiler method updateNative.

private void updateNative(SootMethod method, Function fn, Value env, long flags, List<MarshaledArg> marshaledArgs) {
    for (MarshaledArg value : marshaledArgs) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, value.paramIndex));
        SootMethod afterMethod = ((PointerMarshalerMethod) marshalerMethod).getAfterCallbackCallMethod();
        if (afterMethod != null) {
            Invokestatic invokestatic = new Invokestatic(getInternalName(method.getDeclaringClass()), getInternalName(afterMethod.getDeclaringClass()), afterMethod.getName(), getDescriptor(afterMethod));
            trampolines.add(invokestatic);
            call(fn, invokestatic.getFunctionRef(), env, value.handle, value.object, new IntegerConstant(flags));
        }
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) Invokestatic(org.robovm.compiler.trampoline.Invokestatic) PointerMarshalerMethod(org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod) SootMethod(soot.SootMethod) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) PointerMarshalerMethod(org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Example 25 with MarshalSite

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

MarshalSite (org.robovm.compiler.MarshalerLookup.MarshalSite)27 SootMethod (soot.SootMethod)21 Test (org.junit.Test)18 MarshalerMethod (org.robovm.compiler.MarshalerLookup.MarshalerMethod)9 StructureType (org.robovm.compiler.llvm.StructureType)6 ArrayMarshalerMethod (org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)5 ValueMarshalerMethod (org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod)5 PrimitiveType (org.robovm.compiler.llvm.PrimitiveType)5 PointerMarshalerMethod (org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod)4 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)4 PointerType (org.robovm.compiler.llvm.PointerType)4 ArrayType (org.robovm.compiler.llvm.ArrayType)3 FunctionType (org.robovm.compiler.llvm.FunctionType)3 Type (org.robovm.compiler.llvm.Type)3 Value (org.robovm.compiler.llvm.Value)3 PrimType (soot.PrimType)3 ArrayList (java.util.ArrayList)2 BasicBlockRef (org.robovm.compiler.llvm.BasicBlockRef)2 Bitcast (org.robovm.compiler.llvm.Bitcast)2 ConstantBitcast (org.robovm.compiler.llvm.ConstantBitcast)2