From 99dd7227dcba2fb07f40ac8609b557f8e8875dcf Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Fri, 18 Aug 2017 10:34:54 +0300 Subject: [PATCH] Support Boolean in interop varargs and function pointers invocation --- .../native/kotlin/kotlinx/cinterop/FunctionPointers.kt | 4 ++++ .../src/native/kotlin/kotlinx/cinterop/Varargs.kt | 2 ++ .../org/jetbrains/kotlin/backend/konan/InteropUtils.kt | 1 + backend.native/tests/build.gradle | 4 ++-- backend.native/tests/interop/basics/4.kt | 4 ++-- backend.native/tests/interop/basics/cfunptr.def | 10 ++++++++++ backend.native/tests/interop/basics/funptr.kt | 9 ++++++++- 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/FunctionPointers.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/FunctionPointers.kt index c122e9671f5..37eb70f4d76 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/FunctionPointers.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/FunctionPointers.kt @@ -70,6 +70,10 @@ private fun invokeImplUnitRet(ptr: COpaquePointer, vararg args: Any?): Unit = me callWithVarargs(ptr.rawValue, nativeNullPtr, FFI_TYPE_KIND_VOID, args, emptyArray(), memScope) } +@ExportForCompiler +private fun invokeImplBooleanRet(ptr: COpaquePointer, vararg args: Any?): Boolean = + invokeImplByteRet(ptr, *args).toBoolean() + @ExportForCompiler private fun invokeImplByteRet(ptr: COpaquePointer, vararg args: Any?): Byte = memScoped { val resultBuffer = allocFfiReturnValueBuffer(ByteVar) diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/Varargs.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/Varargs.kt index 0d6e57632c9..bb59a59a48c 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/Varargs.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/Varargs.kt @@ -38,6 +38,8 @@ private tailrec fun convertArgument( FFI_TYPE_KIND_SINT64 } + is Boolean -> convertArgument(argument.toByte(), isVariadic, location, additionalPlacement) + is Byte -> if (isVariadic) { convertArgument(argument.toInt(), isVariadic, location, additionalPlacement) } else { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt index 97d6cc91bee..867e6a44d6c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt @@ -116,6 +116,7 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) { val invokeImpls = mapOf( builtIns.unit to "invokeImplUnitRet", + builtIns.boolean to "invokeImplBooleanRet", builtIns.byte to "invokeImplByteRet", builtIns.short to "invokeImplShortRet", builtIns.int to "invokeImplIntRet", diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index e834a39b284..5a4a89e6c7d 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -2051,7 +2051,7 @@ task interop3(type: RunInteropKonanTest) { task interop4(type: RunInteropKonanTest) { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. - goldValue = "a b -1 2 3 9223372036854775807 0.1 0.2\n1 42\n" + goldValue = "a b -1 2 3 9223372036854775807 0.1 0.2 1 0\n1 42\n" source = "interop/basics/4.kt" interop = 'cstdio' } @@ -2064,7 +2064,7 @@ task interop_bitfields(type: RunInteropKonanTest) { task interop_funptr(type: RunInteropKonanTest) { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. - goldValue = "42\n17\n" + goldValue = "42\n17\n1\n0\n" source = "interop/basics/funptr.kt" interop = 'cfunptr' } diff --git a/backend.native/tests/interop/basics/4.kt b/backend.native/tests/interop/basics/4.kt index 28605ca70f4..120bcf2facf 100644 --- a/backend.native/tests/interop/basics/4.kt +++ b/backend.native/tests/interop/basics/4.kt @@ -5,8 +5,8 @@ val stdout get() = getStdout() fun main(args: Array) { - fprintf(stdout, "%s %s %d %d %d %lld %.1f %.1lf\n", - "a", "b".cstr, (-1).toByte(), 2.toShort(), 3, Long.MAX_VALUE, 0.1.toFloat(), 0.2) + fprintf(stdout, "%s %s %d %d %d %lld %.1f %.1lf %d %d\n", + "a", "b".cstr, (-1).toByte(), 2.toShort(), 3, Long.MAX_VALUE, 0.1.toFloat(), 0.2, true, false) memScoped { val aVar = alloc() diff --git a/backend.native/tests/interop/basics/cfunptr.def b/backend.native/tests/interop/basics/cfunptr.def index 047c59f8b62..526b2ca983e 100644 --- a/backend.native/tests/interop/basics/cfunptr.def +++ b/backend.native/tests/interop/basics/cfunptr.def @@ -41,4 +41,14 @@ typedef int (*doubleToIntPtrType)(double); static doubleToIntPtrType getDoubleToIntPtr() { return &__doubleToInt; +} + +static _Bool __isIntPositive(int x) { + return x > 0; +} + +typedef _Bool (*isIntPositivePtrType)(int); + +static isIntPositivePtrType getIsIntPositivePtr() { + return &__isIntPositive; } \ No newline at end of file diff --git a/backend.native/tests/interop/basics/funptr.kt b/backend.native/tests/interop/basics/funptr.kt index e1d204863a5..c28452b18bb 100644 --- a/backend.native/tests/interop/basics/funptr.kt +++ b/backend.native/tests/interop/basics/funptr.kt @@ -18,4 +18,11 @@ fun main(args: Array) { getAddPtr()!!(5.1, 12.2) ) ) -} \ No newline at end of file + + val isIntPositivePtr = getIsIntPositivePtr()!! + + printIntPtr(isIntPositivePtr(42).ifThenOneElseZero()) + printIntPtr(isIntPositivePtr(-42).ifThenOneElseZero()) +} + +fun Boolean.ifThenOneElseZero() = if (this) 1 else 0 \ No newline at end of file