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:
committed by
SvyatoslavScherbina
parent
397928b066
commit
d1859dd280
@@ -281,10 +281,12 @@ class CFunction<T : CFunctionType>(override val rawPtr: NativePtr) : CPointed
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The pointer to [CFunction].
|
* The pointer to [CFunction].
|
||||||
|
* TODO: remove.
|
||||||
*/
|
*/
|
||||||
typealias CFunctionPointer<T> = CPointer<CFunction<T>>
|
typealias CFunctionPointer<T> = CPointer<CFunction<T>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The variable containing a [CFunctionPointer].
|
* The variable containing a [CFunctionPointer].
|
||||||
|
* TODO: remove.
|
||||||
*/
|
*/
|
||||||
typealias CFunctionPointerVar<T> = CPointerVarWithValueMappedTo<CFunctionPointer<T>>
|
typealias CFunctionPointerVar<T> = CPointerVarWithValueMappedTo<CFunctionPointer<T>>
|
||||||
+16
-10
@@ -189,8 +189,7 @@ class StubGenerator(
|
|||||||
is PointerType -> {
|
is PointerType -> {
|
||||||
val pointeeType = this.pointeeType
|
val pointeeType = this.pointeeType
|
||||||
if (pointeeType is FunctionType) {
|
if (pointeeType is FunctionType) {
|
||||||
pointeeType.returnType.getStringRepresentation() + " (*)(" +
|
"void*" // TODO
|
||||||
pointeeType.parameterTypes.map { it.getStringRepresentation() }.joinToString(", ") + ")"
|
|
||||||
} else {
|
} else {
|
||||||
pointeeType.getStringRepresentation() + "*"
|
pointeeType.getStringRepresentation() + "*"
|
||||||
}
|
}
|
||||||
@@ -370,10 +369,6 @@ class StubGenerator(
|
|||||||
if (pointeeType.unwrapTypedefs() is VoidType) {
|
if (pointeeType.unwrapTypedefs() is VoidType) {
|
||||||
val info = TypeInfo.Pointer("COpaque")
|
val info = TypeInfo.Pointer("COpaque")
|
||||||
TypeMirror.ByValue("COpaquePointerVar", info, "COpaquePointer")
|
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 {
|
} else {
|
||||||
val pointeeMirror = mirror(pointeeType)
|
val pointeeMirror = mirror(pointeeType)
|
||||||
val info = TypeInfo.Pointer(pointeeMirror.pointedTypeName)
|
val info = TypeInfo.Pointer(pointeeMirror.pointedTypeName)
|
||||||
@@ -387,6 +382,8 @@ class StubGenerator(
|
|||||||
byRefTypeMirror("CArray<${elemMirror.pointedTypeName}>")
|
byRefTypeMirror("CArray<${elemMirror.pointedTypeName}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is FunctionType -> byRefTypeMirror("CFunction<${type.kotlinName}>")
|
||||||
|
|
||||||
is Typedef -> {
|
is Typedef -> {
|
||||||
val baseType = mirror(type.def.aliased)
|
val baseType = mirror(type.def.aliased)
|
||||||
val name = type.def.name
|
val name = type.def.name
|
||||||
@@ -793,6 +790,8 @@ class StubGenerator(
|
|||||||
is UInt32Type -> "UInt32"
|
is UInt32Type -> "UInt32"
|
||||||
is IntPtrType, is UIntPtrType, // TODO
|
is IntPtrType, is UIntPtrType, // TODO
|
||||||
is PointerType -> "Pointer"
|
is PointerType -> "Pointer"
|
||||||
|
is Int64Type -> "SInt64"
|
||||||
|
is UInt64Type -> "UInt64"
|
||||||
is ConstArrayType -> getFfiStructType(
|
is ConstArrayType -> getFfiStructType(
|
||||||
Array(type.length.toInt(), { type.elemType }).toList()
|
Array(type.length.toInt(), { type.elemType }).toList()
|
||||||
)
|
)
|
||||||
@@ -800,7 +799,7 @@ class StubGenerator(
|
|||||||
is RecordType -> {
|
is RecordType -> {
|
||||||
val def = type.decl.def!!
|
val def = type.decl.def!!
|
||||||
if (!def.hasNaturalLayout) {
|
if (!def.hasNaturalLayout) {
|
||||||
throw NotImplementedError() // TODO: represent pointer to function as NativePtr instead
|
throw NotImplementedError(type.kotlinName)
|
||||||
}
|
}
|
||||||
getFfiStructType(def.fields.map { it.type })
|
getFfiStructType(def.fields.map { it.type })
|
||||||
}
|
}
|
||||||
@@ -864,8 +863,15 @@ class StubGenerator(
|
|||||||
private fun generateJvmFunctionType(type: FunctionType, name: String) {
|
private fun generateJvmFunctionType(type: FunctionType, name: String) {
|
||||||
val kotlinFunctionType = getKotlinFunctionType(type)
|
val kotlinFunctionType = getKotlinFunctionType(type)
|
||||||
|
|
||||||
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
|
val constructorArgs = try {
|
||||||
type.parameterTypes.map { getArgFfiType(it) }
|
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(", ")
|
val constructorArgsStr = constructorArgs.joinToString(", ")
|
||||||
|
|
||||||
@@ -1198,7 +1204,7 @@ class StubGenerator(
|
|||||||
"$pkgName.externals.${func.name}"
|
"$pkgName.externals.${func.name}"
|
||||||
}
|
}
|
||||||
val functionName = "Java_" + funcFullName.replace("_", "_1").replace('.', '_').replace("$", "_00024")
|
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 -> {
|
KotlinPlatform.NATIVE -> {
|
||||||
val joinedParameters = parameters.joinToString(", ")
|
val joinedParameters = parameters.joinToString(", ")
|
||||||
|
|||||||
Reference in New Issue
Block a user