Search in sources :

Example 16 with PointerType

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

the class NativeMethodCompiler method createNative.

private FunctionRef createNative(ModuleBuilder mb, SootMethod method) {
    String targetInternalName = getInternalName(method.getDeclaringClass());
    String methodName = method.getName();
    String methodDesc = getDescriptor(method);
    FunctionType nativeFunctionType = Types.getNativeFunctionType(methodDesc, method.isStatic());
    String shortName = mangleNativeMethod(targetInternalName, methodName);
    String longName = mangleNativeMethod(targetInternalName, methodName, methodDesc);
    /*
         * To support statically linked native method implementation we create
         * weak stub functions with the same names as the expected JNI functions
         * (long and short names). These will be discarded by the linker if
         * proper functions are available at link time.
         * 
         * The weak stub with the short JNI name just calls the weak stub with
         * the long name.
         * 
         * The weak stub with the long name calls _bcResolveNative() which will
         * try to resolve the native method against dynamically loaded JNI libs.
         * If _bcResolveNative() finds a matching symbol in a dynamic lib or an
         * implementation has previously been registered using JNI
         * RegisterNatives() that will be stored in the native method pointer
         * passed to it and returned. The stub will call the implementation
         * returned by _bcResolveNative(). If no implementation can be found
         * _bcResolveNative() throws an UnsatisfiedLinkError and doesn't return
         * to the stub.
         * 
         * The limitation of this approach is that RegisterNatives() only works
         * for dynamically linked native methods and can only be used prior to
         * the first call of such a method. Native methods can never be rewired
         * or unregistered.
         */
    /*
         * The function with the long JNI name. This is the one that calls
         * _bcResolveNative() and then calls the implementation.
         */
    Function fn = new FunctionBuilder(longName, nativeFunctionType).linkage(weak).build();
    Global g = new Global(Symbols.nativeMethodPtrSymbol(targetInternalName, methodName, methodDesc), new NullConstant(I8_PTR));
    mb.addGlobal(g);
    FunctionRef ldcFn = FunctionBuilder.ldcInternal(targetInternalName).ref();
    Value theClass = call(fn, ldcFn, fn.getParameterRef(0));
    Value implI8Ptr = call(fn, BC_RESOLVE_NATIVE, fn.getParameterRef(0), theClass, mb.getString(methodName), mb.getString(methodDesc), mb.getString(shortName), mb.getString(longName), g.ref());
    Variable nullTest = fn.newVariable(I1);
    fn.add(new Icmp(nullTest, Condition.ne, implI8Ptr, new NullConstant(I8_PTR)));
    Label trueLabel = new Label();
    Label falseLabel = new Label();
    fn.add(new Br(nullTest.ref(), fn.newBasicBlockRef(trueLabel), fn.newBasicBlockRef(falseLabel)));
    fn.newBasicBlock(falseLabel);
    if (fn.getType().getReturnType() instanceof IntegerType) {
        fn.add(new Ret(new IntegerConstant(0, (IntegerType) fn.getType().getReturnType())));
    } else if (fn.getType().getReturnType() instanceof FloatingPointType) {
        fn.add(new Ret(new FloatingPointConstant(0.0, (FloatingPointType) fn.getType().getReturnType())));
    } else if (fn.getType().getReturnType() instanceof PointerType) {
        fn.add(new Ret(new NullConstant((PointerType) fn.getType().getReturnType())));
    } else {
        fn.add(new Ret());
    }
    fn.newBasicBlock(trueLabel);
    Variable impl = fn.newVariable(nativeFunctionType);
    fn.add(new Bitcast(impl, implI8Ptr, impl.getType()));
    Value result = call(fn, impl.ref(), fn.getParameterRefs());
    fn.add(new Ret(result));
    mb.addFunction(fn);
    FunctionRef targetFn = fn.ref();
    if (!isLongNativeFunctionNameRequired(method)) {
        /*
             * Generate a function with the short JNI name. This just calls the
             * function with the long name.
             */
        Function fnShort = new FunctionBuilder(shortName, nativeFunctionType).linkage(weak).build();
        Value resultInner = call(fnShort, fn.ref(), fnShort.getParameterRefs());
        fnShort.add(new Ret(resultInner));
        mb.addFunction(fnShort);
        targetFn = fnShort.ref();
    }
    return targetFn;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Variable(org.robovm.compiler.llvm.Variable) FloatingPointConstant(org.robovm.compiler.llvm.FloatingPointConstant) FunctionType(org.robovm.compiler.llvm.FunctionType) Label(org.robovm.compiler.llvm.Label) NullConstant(org.robovm.compiler.llvm.NullConstant) PointerType(org.robovm.compiler.llvm.PointerType) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) Global(org.robovm.compiler.llvm.Global) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Br(org.robovm.compiler.llvm.Br) IntegerType(org.robovm.compiler.llvm.IntegerType) Function(org.robovm.compiler.llvm.Function) Bitcast(org.robovm.compiler.llvm.Bitcast) Value(org.robovm.compiler.llvm.Value) FunctionRef(org.robovm.compiler.llvm.FunctionRef) Icmp(org.robovm.compiler.llvm.Icmp)

Example 17 with PointerType

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

the class StructMemberMethodCompiler method structMember.

private Function structMember(ModuleBuilder moduleBuilder, SootMethod method) {
    Function function = createMethodFunction(method);
    moduleBuilder.addFunction(function);
    // Get the value of the handle field in the Struct base class and cast it to a <structType>*
    Variable handleI64 = function.newVariable(I64);
    function.add(new Load(handleI64, getFieldPtr(function, function.getParameterRef(1), offsetof(new StructureType(DATA_OBJECT, new StructureType(I64)), 1, 0), I64)));
    Variable handlePtr = function.newVariable(new PointerType(structType));
    function.add(new Inttoptr(handlePtr, handleI64.ref(), handlePtr.getType()));
    // Add 1 since the first type in structType is the superclass type or {}.      
    int offset = getStructMemberOffset(method) + 1;
    Type memberType = getStructMemberType(method);
    Variable memberPtr = function.newVariable(new PointerType(memberType));
    if (memberType != structType.getTypeAt(offset)) {
        // Several @StructMembers of different types have this offset (union)
        Variable tmp = function.newVariable(new PointerType(structType.getTypeAt(offset)));
        function.add(new Getelementptr(tmp, handlePtr.ref(), 0, offset));
        function.add(new Bitcast(memberPtr, tmp.ref(), memberPtr.getType()));
    } else {
        function.add(new Getelementptr(memberPtr, handlePtr.ref(), 0, offset));
    }
    VariableRef env = function.getParameterRef(0);
    if (method.getParameterCount() == 0) {
        // Getter
        Value result = loadValueForGetter(method, function, memberType, memberPtr.ref(), function.getParameterRef(0), true, MarshalerFlags.CALL_TYPE_STRUCT_MEMBER);
        function.add(new Ret(result));
    } else {
        // Setter
        // 'env' is parameter 0, 'this' is at 1, the value we're interested in is at index 2
        Value value = function.getParameterRef(2);
        storeValueForSetter(method, function, memberType, memberPtr.ref(), env, value, MarshalerFlags.CALL_TYPE_STRUCT_MEMBER);
        if (method.getReturnType().equals(VoidType.v())) {
            function.add(new Ret());
        } else {
            function.add(new Ret(function.getParameterRef(1)));
        }
    }
    return function;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Load(org.robovm.compiler.llvm.Load) VariableRef(org.robovm.compiler.llvm.VariableRef) Variable(org.robovm.compiler.llvm.Variable) Inttoptr(org.robovm.compiler.llvm.Inttoptr) PointerType(org.robovm.compiler.llvm.PointerType) Getelementptr(org.robovm.compiler.llvm.Getelementptr) Function(org.robovm.compiler.llvm.Function) StructureType(org.robovm.compiler.llvm.StructureType) PointerType(org.robovm.compiler.llvm.PointerType) Type(org.robovm.compiler.llvm.Type) VoidType(soot.VoidType) Bitcast(org.robovm.compiler.llvm.Bitcast) StructureType(org.robovm.compiler.llvm.StructureType) Value(org.robovm.compiler.llvm.Value)

Example 18 with PointerType

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

the class CallbackMethodCompilerTest method testCreateCallbackCWrapperComplexNestedStructByValReturnAndParameter.

@Test
public void testCreateCallbackCWrapperComplexNestedStructByValReturnAndParameter() {
    StructureType structType = new StructureType(new StructureType(I8, I16), new StructureType(I32, I64), new StructureType(FLOAT, DOUBLE), new ArrayType(100, I32), new ArrayType(10, new StructureType(FLOAT, FLOAT)), new ArrayType(5, new ArrayType(10, I32)), new StructureType(I8_PTR, new PointerType(new StructureType(I32))));
    assertEquals("struct f_0001_0006 {void* m0;void* m1;};\n" + "struct f_0001_0004 {float m0;float m1;};\n" + "struct f_0001_0002 {float m0;double m1;};\n" + "struct f_0001_0001 {int m0;long long m1;};\n" + "struct f_0001_0000 {char m0;short m1;};\n" + "struct f_0001 {struct f_0001_0000 m0;struct f_0001_0001 m1;struct f_0001_0002 m2;int m3[100];struct f_0001_0004 m4[10];int m5[5][10];struct f_0001_0006 m6;};\n" + "struct f_0000_0006 {void* m0;void* m1;};\n" + "struct f_0000_0004 {float m0;float m1;};\n" + "struct f_0000_0002 {float m0;double m1;};\n" + "struct f_0000_0001 {int m0;long long m1;};\n" + "struct f_0000_0000 {char m0;short m1;};\n" + "struct f_0000 {struct f_0000_0000 m0;struct f_0000_0001 m1;struct f_0000_0002 m2;int m3[100];struct f_0000_0004 m4[10];int m5[5][10];struct f_0000_0006 m6;};\n" + "void* f_inner(void*);\n" + "struct f_0000 f(struct f_0001 p0) {\n" + "    return *((struct f_0000*) f_inner((void*) &p0));\n" + "}\n", CallbackMethodCompiler.createCallbackCWrapper(new FunctionType(structType, structType), "f", "f_inner"));
}
Also used : ArrayType(org.robovm.compiler.llvm.ArrayType) StructureType(org.robovm.compiler.llvm.StructureType) FunctionType(org.robovm.compiler.llvm.FunctionType) PointerType(org.robovm.compiler.llvm.PointerType) Test(org.junit.Test)

Example 19 with PointerType

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

the class BridgeMethodCompilerTest method testCreateBridgeCWrapperPointerParameters.

@Test
public void testCreateBridgeCWrapperPointerParameters() {
    FunctionType functionType = new FunctionType(VOID, I8_PTR, new PointerType(new StructureType(I32)));
    assertEquals("void f(void* target, void* p0, void* p1) {\n" + "    ((void (*)(void*, void*)) target)(p0, p1);\n" + "}\n", BridgeMethodCompiler.createBridgeCWrapper(functionType.getReturnType(), functionType.getParameterTypes(), functionType.getParameterTypes(), "f"));
}
Also used : FunctionType(org.robovm.compiler.llvm.FunctionType) StructureType(org.robovm.compiler.llvm.StructureType) PointerType(org.robovm.compiler.llvm.PointerType) Test(org.junit.Test)

Example 20 with PointerType

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

the class BridgeMethodCompilerTest method testCreateBridgeCWrapperComplexNestedStructByValReturnAndParameter.

@Test
public void testCreateBridgeCWrapperComplexNestedStructByValReturnAndParameter() {
    StructureType structType = new StructureType(new StructureType(I8, I16), new StructureType(I32, I64), new StructureType(FLOAT, DOUBLE), new ArrayType(100, I32), new ArrayType(10, new StructureType(FLOAT, FLOAT)), new ArrayType(5, new ArrayType(10, I32)), new StructureType(I8_PTR, new PointerType(new StructureType(I32))));
    FunctionType functionType = new FunctionType(structType, structType);
    assertEquals("void f(void* target, void* ret, void* p0) {\n" + "    struct f_0001_0006 {void* m0;void* m1;};\n" + "    struct f_0001_0004 {float m0;float m1;};\n" + "    struct f_0001_0002 {float m0;double m1;};\n" + "    struct f_0001_0001 {int m0;long long m1;};\n" + "    struct f_0001_0000 {char m0;short m1;};\n" + "    struct f_0001 {struct f_0001_0000 m0;struct f_0001_0001 m1;struct f_0001_0002 m2;int m3[100];struct f_0001_0004 m4[10];int m5[5][10];struct f_0001_0006 m6;};\n" + "    struct f_0000_0006 {void* m0;void* m1;};\n" + "    struct f_0000_0004 {float m0;float m1;};\n" + "    struct f_0000_0002 {float m0;double m1;};\n" + "    struct f_0000_0001 {int m0;long long m1;};\n" + "    struct f_0000_0000 {char m0;short m1;};\n" + "    struct f_0000 {struct f_0000_0000 m0;struct f_0000_0001 m1;struct f_0000_0002 m2;int m3[100];struct f_0000_0004 m4[10];int m5[5][10];struct f_0000_0006 m6;};\n" + "    *((struct f_0000*)ret) = ((struct f_0000 (*)(struct f_0001)) target)(*((struct f_0001*)p0));\n" + "}\n", BridgeMethodCompiler.createBridgeCWrapper(functionType.getReturnType(), functionType.getParameterTypes(), functionType.getParameterTypes(), "f"));
}
Also used : ArrayType(org.robovm.compiler.llvm.ArrayType) StructureType(org.robovm.compiler.llvm.StructureType) FunctionType(org.robovm.compiler.llvm.FunctionType) PointerType(org.robovm.compiler.llvm.PointerType) Test(org.junit.Test)

Aggregations

PointerType (org.robovm.compiler.llvm.PointerType)22 Variable (org.robovm.compiler.llvm.Variable)13 FunctionType (org.robovm.compiler.llvm.FunctionType)11 StructureType (org.robovm.compiler.llvm.StructureType)11 Value (org.robovm.compiler.llvm.Value)9 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)8 Load (org.robovm.compiler.llvm.Load)8 Type (org.robovm.compiler.llvm.Type)8 ArrayType (org.robovm.compiler.llvm.ArrayType)7 Bitcast (org.robovm.compiler.llvm.Bitcast)7 ConstantBitcast (org.robovm.compiler.llvm.ConstantBitcast)6 FunctionRef (org.robovm.compiler.llvm.FunctionRef)6 Getelementptr (org.robovm.compiler.llvm.Getelementptr)6 NullConstant (org.robovm.compiler.llvm.NullConstant)6 Ret (org.robovm.compiler.llvm.Ret)6 PrimType (soot.PrimType)6 Br (org.robovm.compiler.llvm.Br)5 Function (org.robovm.compiler.llvm.Function)5 Icmp (org.robovm.compiler.llvm.Icmp)5 IntegerType (org.robovm.compiler.llvm.IntegerType)5