From 7f0b8a67788e6a82deea4d0aecaeca7a008289e5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Fri, 31 Mar 2017 13:53:39 +0300 Subject: [PATCH] Fix number of interop issues --- .../kotlin/kotlinx/cinterop/JvmNativeMem.kt | 6 +- .../main/kotlin/kotlinx/cinterop/Generated.kt | 192 ++++++++++++------ .../src/main/kotlin/kotlinx/cinterop/Types.kt | 34 +++- .../src/main/kotlin/kotlinx/cinterop/Utils.kt | 7 +- .../kotlin/kotlinx/cinterop/NativeMem.kt | 8 +- .../native/interop/gen/jvm/StubGenerator.kt | 5 +- .../kotlin/backend/konan/InteropUtils.kt | 10 +- .../kotlin/backend/konan/llvm/LlvmUtils.kt | 2 +- 8 files changed, 172 insertions(+), 92 deletions(-) diff --git a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmNativeMem.kt b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmNativeMem.kt index 2b2ae6df163..6ed993d2376 100644 --- a/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmNativeMem.kt +++ b/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmNativeMem.kt @@ -33,7 +33,7 @@ private val dataModel: DataModel = when (System.getProperty("sun.arch.data.model else -> throw IllegalStateException() } -internal val pointerSize: Int = dataModel.pointerSize.toInt() +val pointerSize: Int = dataModel.pointerSize.toInt() object nativeMemUtils { fun getByte(mem: NativePointed) = unsafe.getByte(mem.address) @@ -89,8 +89,8 @@ object nativeMemUtils { return interpretPointed(address) } - fun free(mem: NativePointed) { - unsafe.freeMemory(mem.rawPtr) + fun free(mem: NativePtr) { + unsafe.freeMemory(mem) } private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) { diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Generated.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Generated.kt index 2c84c18dcf6..18c3e5b2f34 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Generated.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Generated.kt @@ -14,110 +14,168 @@ * limitations under the License. */ +@file:Suppress("FINAL_UPPER_BOUND", "NOTHING_TO_INLINE") + package kotlinx.cinterop -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 1L).value - -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 1L).value = value -} - -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Byte") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 1L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 1) -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 2L).value +@JvmName("plus\$Byte") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 2L).value = value +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Short") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 2L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 2) -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 4L).value +@JvmName("plus\$Short") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 4L).value = value +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Int") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 4L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 4) -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 8L).value +@JvmName("plus\$Int") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 8L).value = value +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Long") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 8L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 8) -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 4L).value +@JvmName("plus\$Long") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 4L).value = value +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Float") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 4L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 4) -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.get(index: Int): T = - interpretPointed>(this.rawValue + index * 8L).value +@JvmName("plus\$Float") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() -@Suppress("FINAL_UPPER_BOUND") -operator fun CPointer>.set(index: Int, value: T) { - interpretPointed>(this.rawValue + index * 8L).value = value +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") @JvmName("plus\$Double") -operator fun CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * 8L) +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * 8) + +@JvmName("plus\$Double") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() + +inline operator fun CPointer>.get(index: Int): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Int, value: T) { + (this + index)!!.pointed.value = value +} + +inline operator fun CPointer>.get(index: Long): T = + (this + index)!!.pointed.value + +inline operator fun CPointer>.set(index: Long, value: T) { + (this + index)!!.pointed.value = value +} /* Generated by: #!/bin/bash function gen { -echo '@Suppress("FINAL_UPPER_BOUND")' -echo "operator fun CPointer<${1}VarOf>.get(index: Int): T =" -echo " interpretPointed<${1}VarOf>(this.rawValue + index * ${2}L).value" +echo "@JvmName(\"plus\\\$$1\")" +echo "inline operator fun > CPointer?.plus(index: Long): CPointer? =" +echo " interpretCPointer(this.rawValue + index * ${2})" echo -echo '@Suppress("FINAL_UPPER_BOUND")' -echo "operator fun CPointer<${1}VarOf>.set(index: Int, value: T) {" -echo " interpretPointed<${1}VarOf>(this.rawValue + index * ${2}L).value = value" +echo "@JvmName(\"plus\\\$$1\")" +echo "inline operator fun > CPointer?.plus(index: Int): CPointer? =" +echo " this + index.toLong()" +echo +echo "inline operator fun CPointer<${1}VarOf>.get(index: Int): T =" +echo " (this + index)!!.pointed.value" +echo +echo "inline operator fun CPointer<${1}VarOf>.set(index: Int, value: T) {" +echo " (this + index)!!.pointed.value = value" echo '}' echo -echo '@Suppress("FINAL_UPPER_BOUND")' -echo "@JvmName(\"plus\\\$$1\")" -echo "operator fun CPointer?.plus(index: Int): CPointer? =" -echo " interpretCPointer(this.rawValue + index * ${2}L)" +echo "inline operator fun CPointer<${1}VarOf>.get(index: Long): T =" +echo " (this + index)!!.pointed.value" +echo +echo "inline operator fun CPointer<${1}VarOf>.set(index: Long, value: T) {" +echo " (this + index)!!.pointed.value = value" +echo '}' echo } diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt index 77db638619c..e57499ff797 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt @@ -346,19 +346,33 @@ inline operator fun CPointer.get(index: Long): T { inline operator fun CPointer.get(index: Int): T = this.get(index.toLong()) -@Suppress("FINAL_UPPER_BOUND") -operator fun > CPointer>.get(index: Int): T? = - interpretPointed>(this.rawValue + index * pointerSize.toLong()).value +@Suppress("NOTHING_TO_INLINE") +@JvmName("plus\$CPointer") +inline operator fun > CPointer?.plus(index: Long): CPointer? = + interpretCPointer(this.rawValue + index * pointerSize) -@Suppress("FINAL_UPPER_BOUND") -operator fun > CPointer>.set(index: Int, value: T?) { - interpretPointed>(this.rawValue + index * pointerSize.toLong()).value = value +@Suppress("NOTHING_TO_INLINE") +@JvmName("plus\$CPointer") +inline operator fun > CPointer?.plus(index: Int): CPointer? = + this + index.toLong() + +@Suppress("NOTHING_TO_INLINE") +inline operator fun > CPointer>.get(index: Int): T? = + (this + index)!!.pointed.value + +@Suppress("NOTHING_TO_INLINE") +inline operator fun > CPointer>.set(index: Int, value: T?) { + (this + index)!!.pointed.value = value } -@Suppress("FINAL_UPPER_BOUND") -@JvmName("plus\$CPointer") -operator fun > CPointer?.plus(index: Int): CPointer? = - interpretCPointer(this.rawValue + index * pointerSize.toLong()) +@Suppress("NOTHING_TO_INLINE") +inline operator fun > CPointer>.get(index: Long): T? = + (this + index)!!.pointed.value + +@Suppress("NOTHING_TO_INLINE") +inline operator fun > CPointer>.set(index: Long, value: T?) { + (this + index)!!.pointed.value = value +} typealias CArrayPointer = CPointer typealias CArrayPointerVar = CPointerVar diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt index b2689d0da33..18be14343e1 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt @@ -24,13 +24,16 @@ interface NativePlacement { } interface NativeFreeablePlacement : NativePlacement { - fun free(mem: NativePointed) + fun free(mem: NativePtr) } +fun NativeFreeablePlacement.free(pointer: CPointer<*>) = this.free(pointer.rawValue) +fun NativeFreeablePlacement.free(pointed: NativePointed) = this.free(pointed.rawPtr) + object nativeHeap : NativeFreeablePlacement { override fun alloc(size: Long, align: Int) = nativeMemUtils.alloc(size, align) - override fun free(mem: NativePointed) = nativeMemUtils.free(mem) + override fun free(mem: NativePtr) = nativeMemUtils.free(mem) } // TODO: implement optimally diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt index ba9572e4d4f..7b11b00d4ae 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt @@ -2,7 +2,7 @@ package kotlinx.cinterop import konan.internal.Intrinsic -internal inline val pointerSize: Int +inline val pointerSize: Int get() = getPointerSize() @Intrinsic external fun getPointerSize(): Int @@ -64,8 +64,8 @@ object nativeMemUtils { return interpretPointed(ptr) } - fun free(mem: NativePointed) { - free(mem.rawPtr) + fun free(mem: NativePtr) { + cfree(mem) } } @@ -73,4 +73,4 @@ object nativeMemUtils { private external fun malloc(size: Long, align: Int): NativePtr @SymbolName("Kotlin_interop_free") -private external fun free(ptr: NativePtr) \ No newline at end of file +private external fun cfree(ptr: NativePtr) \ No newline at end of file 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 f7abb580c2b..06791686ffc 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 @@ -1019,7 +1019,10 @@ class StubGenerator( private fun FunctionType.requiresAdapterOnNative(): Boolean { assert (platform == KotlinPlatform.NATIVE) - return (parameterTypes + returnType).any { it.unwrapTypedefs() is RecordType } + return (parameterTypes + returnType).any { + val unwrappedType = it.unwrapTypedefs() + unwrappedType is RecordType || (unwrappedType is EnumType && unwrappedType.def.isStrictEnum) + } } private fun generateNativeFunctionType(type: FunctionType, name: String) { 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 d5b748b2edd..51d0b04da98 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 @@ -79,12 +79,16 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) { val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single() + val variableClass = packageScope.getContributedClassifier("CVariable") as ClassDescriptor + val arrayGetByIntIndex = packageScope.getContributedFunctions("get").single { - KotlinBuiltIns.isInt(it.valueParameters.single().type) && it.isInline + KotlinBuiltIns.isInt(it.valueParameters.single().type) && + it.typeParameters.single().upperBounds.single() == variableClass.defaultType } val arrayGetByLongIndex = packageScope.getContributedFunctions("get").single { - KotlinBuiltIns.isLong(it.valueParameters.single().type) && it.isInline + KotlinBuiltIns.isLong(it.valueParameters.single().type) && + it.typeParameters.single().upperBounds.single() == variableClass.defaultType } val allocUninitializedArrayWithIntLength = packageScope.getContributedFunctions("allocArray").single { @@ -101,8 +105,6 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) { val typeOf = packageScope.getContributedFunctions("typeOf").single() - val variableClass = packageScope.getContributedClassifier("CVariable") as ClassDescriptor - val variableTypeClass = variableClass.unsubstitutedInnerClassesScope.getContributedClassifier("Type") as ClassDescriptor diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 7a757f7fa1c..660545194ed 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -172,7 +172,7 @@ internal fun RuntimeAware.isObjectType(type: LLVMTypeRef): Boolean { * Reads [size] bytes contained in this array. */ internal fun CArrayPointer.getBytes(size: Long) = - (0 .. size-1).map { this[it].value }.toByteArray() + (0 .. size-1).map { this[it] }.toByteArray() internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef { return getGlobalType(ptrToFunction)