Interop/StubGenerator: do not treat array-typed fields as pointers
when passing structs by value through libffi
This commit is contained in:
+22
-8
@@ -578,6 +578,11 @@ class StubGenerator(
|
|||||||
out("}")
|
out("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getFfiStructType(elementTypes: List<Type>) =
|
||||||
|
"Struct(" +
|
||||||
|
elementTypes.map { getFfiType(it) }.joinToString(", ") +
|
||||||
|
")"
|
||||||
|
|
||||||
private fun getFfiType(type: Type): String {
|
private fun getFfiType(type: Type): String {
|
||||||
return when(type) {
|
return when(type) {
|
||||||
is VoidType -> "Void"
|
is VoidType -> "Void"
|
||||||
@@ -588,29 +593,38 @@ class StubGenerator(
|
|||||||
is Int32Type -> "SInt32"
|
is Int32Type -> "SInt32"
|
||||||
is UInt32Type -> "UInt32"
|
is UInt32Type -> "UInt32"
|
||||||
is IntPtrType, is UIntPtrType, // TODO
|
is IntPtrType, is UIntPtrType, // TODO
|
||||||
is PointerType, is ArrayType -> "Pointer"
|
is PointerType -> "Pointer"
|
||||||
|
is ConstArrayType -> getFfiStructType(
|
||||||
|
Array(type.length.toInt(), { type.elemType }).toList()
|
||||||
|
)
|
||||||
is EnumType -> getFfiType(type.def.baseType)
|
is EnumType -> getFfiType(type.def.baseType)
|
||||||
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() // TODO: represent pointer to function as NativePtr instead
|
||||||
}
|
}
|
||||||
"Struct(" + def.fields.map {
|
getFfiStructType(def.fields.map { it.type })
|
||||||
getFfiType(it.type)
|
|
||||||
}.joinToString(", ") + ")"
|
|
||||||
}
|
}
|
||||||
else -> throw NotImplementedError(type.toString())
|
else -> throw NotImplementedError(type.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getArgFfiType(type: Type) = when (type) {
|
||||||
|
is ArrayType -> "Pointer"
|
||||||
|
else -> getFfiType(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getRetValFfiType(type: Type) = getArgFfiType(type)
|
||||||
|
|
||||||
private fun generateFunctionType(type: FunctionType, name: String) {
|
private fun generateFunctionType(type: FunctionType, name: String) {
|
||||||
val kotlinFunctionType = getKotlinFunctionType(type)
|
val kotlinFunctionType = getKotlinFunctionType(type)
|
||||||
|
|
||||||
val constructorArgs = listOf(type.returnType, *type.parameterTypes.toTypedArray()).map {
|
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
|
||||||
getFfiType(it)
|
type.parameterTypes.map { getArgFfiType(it) }
|
||||||
}.joinToString(", ")
|
|
||||||
|
|
||||||
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgs) {")
|
val constructorArgsStr = constructorArgs.joinToString(", ")
|
||||||
|
|
||||||
|
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgsStr) {")
|
||||||
indent {
|
indent {
|
||||||
out("override fun invoke(function: $kotlinFunctionType, args: NativeArray<NativePtrBox>, ret: NativePtr) {")
|
out("override fun invoke(function: $kotlinFunctionType, args: NativeArray<NativePtrBox>, ret: NativePtr) {")
|
||||||
indent {
|
indent {
|
||||||
|
|||||||
Reference in New Issue
Block a user