From 2d2c79c54cb0c85fc4e54ed72ac6ef496ce7bce0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Fri, 14 Oct 2016 16:05:50 +0300 Subject: [PATCH] Interop/StubGenerator: do not treat array-typed fields as pointers when passing structs by value through libffi --- .../native/interop/gen/jvm/StubGenerator.kt | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) 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 72bce02dbfb..40f3f140f56 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 @@ -578,6 +578,11 @@ class StubGenerator( out("}") } + private fun getFfiStructType(elementTypes: List) = + "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, ret: NativePtr) {") indent {