Interop/StubGenerator: do not treat array-typed fields as pointers

when passing structs by value through libffi
This commit is contained in:
Svyatoslav Scherbina
2016-10-14 16:05:50 +03:00
parent bd449b2ac3
commit 2d2c79c54c
@@ -578,6 +578,11 @@ class StubGenerator(
out("}")
}
private fun getFfiStructType(elementTypes: List<Type>) =
"Struct(" +
elementTypes.map { getFfiType(it) }.joinToString(", ") +
")"
private fun getFfiType(type: Type): String {
return when(type) {
is VoidType -> "Void"
@@ -588,29 +593,38 @@ class StubGenerator(
is Int32Type -> "SInt32"
is UInt32Type -> "UInt32"
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 RecordType -> {
val def = type.decl.def!!
if (!def.hasNaturalLayout) {
throw NotImplementedError() // TODO: represent pointer to function as NativePtr instead
}
"Struct(" + def.fields.map {
getFfiType(it.type)
}.joinToString(", ") + ")"
getFfiStructType(def.fields.map { it.type })
}
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) {
val kotlinFunctionType = getKotlinFunctionType(type)
val constructorArgs = listOf(type.returnType, *type.parameterTypes.toTypedArray()).map {
getFfiType(it)
}.joinToString(", ")
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
type.parameterTypes.map { getArgFfiType(it) }
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgs) {")
val constructorArgsStr = constructorArgs.joinToString(", ")
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgsStr) {")
indent {
out("override fun invoke(function: $kotlinFunctionType, args: NativeArray<NativePtrBox>, ret: NativePtr) {")
indent {