diff --git a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt index e38e19ce54d..fefdd69d1fd 100644 --- a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt +++ b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt @@ -8,42 +8,62 @@ fun bitsToDouble(bits: Long): Double = java.lang.Double.longBitsToDouble(bits) // TODO: the functions below should eventually be intrinsified -inline fun Number.signExtend(): R { - val returnValueClass = R::class.java - when (returnValueClass) { - java.lang.Byte::class.java -> if (this is Byte) { - return this.toByte() as R - } - java.lang.Short::class.java -> if (this is Byte || this is Short) { - return this.toShort() as R - } - java.lang.Integer::class.java -> if (this is Byte || this is Short || this is Int) { - return this.toInt() as R - } - java.lang.Long::class.java -> if (this is Byte || this is Short || this is Int || this is Long) { - return this.toLong() as R - } - } - - throw Error("unable to sign extend ${this.javaClass.simpleName} \"$this\" to ${returnValueClass.simpleName}") +inline fun Byte.signExtend(): R = when (R::class.java) { + java.lang.Byte::class.java -> this.toByte() as R + java.lang.Short::class.java -> this.toShort() as R + java.lang.Integer::class.java -> this.toInt() as R + java.lang.Long::class.java -> this.toLong() as R + else -> this.invalidSignExtension() } -inline fun Number.narrow(): R { - val returnValueClass = R::class.java - when (returnValueClass) { - java.lang.Byte::class.java -> if (this is Byte || this is Short || this is Int || this is Long) { - return this.toByte() as R - } - java.lang.Short::class.java -> if (this is Short || this is Int || this is Long) { - return this.toShort() as R - } - java.lang.Integer::class.java -> if (this is Int || this is Long) { - return this.toInt() as R - } - java.lang.Long::class.java -> if (this is Long) { - return this.toLong() as R - } - } - - throw Error("unable to narrow ${this.javaClass.simpleName} \"$this\" to ${returnValueClass.simpleName}") +inline fun Short.signExtend(): R = when (R::class.java) { + java.lang.Short::class.java -> this.toShort() as R + java.lang.Integer::class.java -> this.toInt() as R + java.lang.Long::class.java -> this.toLong() as R + else -> this.invalidSignExtension() +} + +inline fun Int.signExtend(): R = when (R::class.java) { + java.lang.Integer::class.java -> this.toInt() as R + java.lang.Long::class.java -> this.toLong() as R + else -> this.invalidSignExtension() +} + +inline fun Long.signExtend(): R = when (R::class.java) { + java.lang.Long::class.java -> this.toLong() as R + else -> this.invalidSignExtension() +} + +inline fun Number.invalidSignExtension(): R { + throw Error("unable to sign extend ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}") +} + +inline fun Byte.narrow(): R = when (R::class.java) { + java.lang.Byte::class.java -> this.toByte() as R + else -> this.invalidNarrowing() +} + +inline fun Short.narrow(): R = when (R::class.java) { + java.lang.Byte::class.java -> this.toByte() as R + java.lang.Short::class.java -> this.toShort() as R + else -> this.invalidNarrowing() +} + +inline fun Int.narrow(): R = when (R::class.java) { + java.lang.Byte::class.java -> this.toByte() as R + java.lang.Short::class.java -> this.toShort() as R + java.lang.Integer::class.java -> this.toInt() as R + else -> this.invalidNarrowing() +} + +inline fun Long.narrow(): R = when (R::class.java) { + java.lang.Byte::class.java -> this.toByte() as R + java.lang.Short::class.java -> this.toShort() as R + java.lang.Integer::class.java -> this.toInt() as R + java.lang.Long::class.java -> this.toLong() as R + else -> this.invalidNarrowing() +} + +inline fun Number.invalidNarrowing(): R { + throw Error("unable to narrow ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}") } diff --git a/samples/socket/EchoServer.kt b/samples/socket/EchoServer.kt index bec850a660e..090e277bbb4 100644 --- a/samples/socket/EchoServer.kt +++ b/samples/socket/EchoServer.kt @@ -20,7 +20,7 @@ fun main(args: Array) { with(serverAddr) { memset(this.ptr, 0, sockaddr_in.size) - sin_family.value = AF_INET.toByte() + sin_family.value = AF_INET.narrow() sin_addr.s_addr.value = htons(0).toInt() sin_port.value = htons(port) }