Interop, backend: add bitsTo{Float,Double} intrinsics

This commit is contained in:
Svyatoslav Scherbina
2017-02-20 17:01:55 +07:00
committed by SvyatoslavScherbina
parent 9afd9360b3
commit 01dd86d3b5
4 changed files with 45 additions and 3 deletions
@@ -1,4 +1,7 @@
package kotlinx.cinterop
internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes)
internal fun encodeToUtf8(str: String) = str.toByteArray()
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)
@@ -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
}
}
@Intrinsic
external fun bitsToFloat(bits: Int): Float
@Intrinsic
external fun bitsToDouble(bits: Long): Double
@@ -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) =
@@ -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)!!
}
}
}
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)