From 01dd86d3b5bb9c1d322b6eb05786e063779f745c Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 20 Feb 2017 17:01:55 +0700 Subject: [PATCH] Interop, backend: add bitsTo{Float,Double} intrinsics --- .../jvm/kotlin/kotlinx/cinterop/JvmUtils.kt | 5 +++- .../kotlin/kotlinx/cinterop/NativeUtils.kt | 10 ++++++- .../kotlin/backend/konan/InteropUtils.kt | 4 +++ .../backend/konan/lower/InteropLowering.kt | 29 ++++++++++++++++++- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt index 5c7bf64a12c..4379ac7784e 100644 --- a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt +++ b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt @@ -1,4 +1,7 @@ package kotlinx.cinterop internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes) -internal fun encodeToUtf8(str: String) = str.toByteArray() \ No newline at end of file +internal fun encodeToUtf8(str: String) = str.toByteArray() + +fun bitsToFloat(bits: Int): Float = java.lang.Float.intBitsToFloat(bits) +fun bitsToDouble(bits: Long): Double = java.lang.Double.longBitsToDouble(bits) \ No newline at end of file diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt index 16dcce28e61..840f0ca137c 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt @@ -1,5 +1,7 @@ package kotlinx.cinterop +import konan.internal.Intrinsic + internal fun decodeFromUtf8(bytes: ByteArray): String = kotlin.text.fromUtf8Array(bytes, 0, bytes.size) fun encodeToUtf8(str: String): ByteArray { @@ -13,4 +15,10 @@ fun encodeToUtf8(str: String): ByteArray { result[index] = char.toByte() } return result -} \ No newline at end of file +} + +@Intrinsic +external fun bitsToFloat(bits: Int): Float + +@Intrinsic +external fun bitsToDouble(bits: Long): Double \ No newline at end of file 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 5ccf531c3b8..1466e6bed27 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 @@ -93,6 +93,10 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) { val nativePtrPlusLong = nativePtr.unsubstitutedMemberScope.getContributedFunctions("plus").single() + val bitsToFloat = packageScope.getContributedFunctions("bitsToFloat").single() + + val bitsToDouble = packageScope.getContributedFunctions("bitsToDouble").single() + } private fun MemberScope.getContributedVariables(name: String) = diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt index 979c0e2873b..fc65acd814c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name @@ -186,6 +187,26 @@ private class InteropTransformer(val context: Context) : IrBuildingTransformer(c builder.typeOf(type) ?: expression } + interop.bitsToFloat -> { + val argument = expression.getValueArgument(0) + if (argument is IrConst<*> && argument.kind == IrConstKind.Int) { + val floatValue = kotlinx.cinterop.bitsToFloat(argument.value as Int) + builder.irFloat(floatValue) + } else { + expression + } + } + + interop.bitsToDouble -> { + val argument = expression.getValueArgument(0) + if (argument is IrConst<*> && argument.kind == IrConstKind.Long) { + val doubleValue = kotlinx.cinterop.bitsToDouble(argument.value as Long) + builder.irDouble(doubleValue) + } else { + expression + } + } + else -> expression } } @@ -194,4 +215,10 @@ private class InteropTransformer(val context: Context) : IrBuildingTransformer(c val typeParameter = descriptor.original.typeParameters.single() return getTypeArgument(typeParameter)!! } -} \ No newline at end of file +} + +private fun IrBuilder.irFloat(value: Float) = + IrConstImpl.float(startOffset, endOffset, context.builtIns.floatType, value) + +private fun IrBuilder.irDouble(value: Double) = + IrConstImpl.double(startOffset, endOffset, context.builtIns.doubleType, value) \ No newline at end of file