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.
This commit is contained in:
Svyatoslav Scherbina
2017-03-15 14:17:01 +07:00
committed by SvyatoslavScherbina
parent 397928b066
commit d1859dd280
2 changed files with 18 additions and 10 deletions
@@ -281,10 +281,12 @@ class CFunction<T : CFunctionType>(override val rawPtr: NativePtr) : CPointed
/**
* The pointer to [CFunction].
* TODO: remove.
*/
typealias CFunctionPointer<T> = CPointer<CFunction<T>>
/**
* The variable containing a [CFunctionPointer].
* TODO: remove.
*/
typealias CFunctionPointerVar<T> = CPointerVarWithValueMappedTo<CFunctionPointer<T>>
@@ -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(", ")