From d1859dd2804ad04f405ef2db914815f73128f3eb Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Wed, 15 Mar 2017 14:17:01 +0700 Subject: [PATCH] Improve function types support in interop * Support `typedef` to function type without pointer; * Support 64-bit integers in function types; * Generate opaque function type on JVM if not supported. Fix other minor bugs. --- .../src/main/kotlin/kotlinx/cinterop/Types.kt | 2 ++ .../native/interop/gen/jvm/StubGenerator.kt | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt index 096a226b107..eed28c06d06 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt @@ -281,10 +281,12 @@ class CFunction(override val rawPtr: NativePtr) : CPointed /** * The pointer to [CFunction]. + * TODO: remove. */ typealias CFunctionPointer = CPointer> /** * The variable containing a [CFunctionPointer]. + * TODO: remove. */ typealias CFunctionPointerVar = CPointerVarWithValueMappedTo> \ No newline at end of file diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt index 24822117650..9a816e7671b 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt @@ -189,8 +189,7 @@ class StubGenerator( is PointerType -> { val pointeeType = this.pointeeType if (pointeeType is FunctionType) { - pointeeType.returnType.getStringRepresentation() + " (*)(" + - pointeeType.parameterTypes.map { it.getStringRepresentation() }.joinToString(", ") + ")" + "void*" // TODO } else { pointeeType.getStringRepresentation() + "*" } @@ -370,10 +369,6 @@ class StubGenerator( if (pointeeType.unwrapTypedefs() is VoidType) { val info = TypeInfo.Pointer("COpaque") TypeMirror.ByValue("COpaquePointerVar", info, "COpaquePointer") - } else if (pointeeType is FunctionType) { - val kotlinName = pointeeType.kotlinName - val info = TypeInfo.Pointer("CFunction<$kotlinName>") - TypeMirror.ByValue("CFunctionPointerVar<$kotlinName>", info, "CFunctionPointer<$kotlinName>") } else { val pointeeMirror = mirror(pointeeType) val info = TypeInfo.Pointer(pointeeMirror.pointedTypeName) @@ -387,6 +382,8 @@ class StubGenerator( byRefTypeMirror("CArray<${elemMirror.pointedTypeName}>") } + is FunctionType -> byRefTypeMirror("CFunction<${type.kotlinName}>") + is Typedef -> { val baseType = mirror(type.def.aliased) val name = type.def.name @@ -793,6 +790,8 @@ class StubGenerator( is UInt32Type -> "UInt32" is IntPtrType, is UIntPtrType, // TODO is PointerType -> "Pointer" + is Int64Type -> "SInt64" + is UInt64Type -> "UInt64" is ConstArrayType -> getFfiStructType( Array(type.length.toInt(), { type.elemType }).toList() ) @@ -800,7 +799,7 @@ class StubGenerator( is RecordType -> { val def = type.decl.def!! if (!def.hasNaturalLayout) { - throw NotImplementedError() // TODO: represent pointer to function as NativePtr instead + throw NotImplementedError(type.kotlinName) } getFfiStructType(def.fields.map { it.type }) } @@ -864,8 +863,15 @@ class StubGenerator( private fun generateJvmFunctionType(type: FunctionType, name: String) { val kotlinFunctionType = getKotlinFunctionType(type) - val constructorArgs = listOf(getRetValFfiType(type.returnType)) + - type.parameterTypes.map { getArgFfiType(it) } + val constructorArgs = try { + listOf(getRetValFfiType(type.returnType)) + + type.parameterTypes.map { getArgFfiType(it) } + + } catch (e: Throwable) { + println("Warning: cannot generate definition for function type $name") + out("object $name : CFunctionType {}") + return + } val constructorArgsStr = constructorArgs.joinToString(", ") @@ -1198,7 +1204,7 @@ class StubGenerator( "$pkgName.externals.${func.name}" } val functionName = "Java_" + funcFullName.replace("_", "_1").replace('.', '_').replace("$", "_00024") - "JNIEXPORT $cReturnType JNICALL $functionName (JNIEnv *env, jobject obj$joinedParameters)" + "JNIEXPORT $cReturnType JNICALL $functionName (JNIEnv *jniEnv, jobject externalsObj$joinedParameters)" } KotlinPlatform.NATIVE -> { val joinedParameters = parameters.joinToString(", ")