Fix number of interop issues

This commit is contained in:
Svyatoslav Scherbina
2017-03-31 13:53:39 +03:00
committed by SvyatoslavScherbina
parent 89552fa2c8
commit 7f0b8a6778
8 changed files with 172 additions and 92 deletions
@@ -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<NativeAllocated>(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")) {
@@ -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 <T : Byte> CPointer<ByteVarOf<T>>.get(index: Int): T =
interpretPointed<ByteVarOf<T>>(this.rawValue + index * 1L).value
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Byte> CPointer<ByteVarOf<T>>.set(index: Int, value: T) {
interpretPointed<ByteVarOf<T>>(this.rawValue + index * 1L).value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Byte")
operator fun <T : ByteVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 1L)
inline operator fun <T : ByteVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 1)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Short> CPointer<ShortVarOf<T>>.get(index: Int): T =
interpretPointed<ShortVarOf<T>>(this.rawValue + index * 2L).value
@JvmName("plus\$Byte")
inline operator fun <T : ByteVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Short> CPointer<ShortVarOf<T>>.set(index: Int, value: T) {
interpretPointed<ShortVarOf<T>>(this.rawValue + index * 2L).value = value
inline operator fun <T : Byte> CPointer<ByteVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Byte> CPointer<ByteVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Byte> CPointer<ByteVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Byte> CPointer<ByteVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Short")
operator fun <T : ShortVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 2L)
inline operator fun <T : ShortVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 2)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Int> CPointer<IntVarOf<T>>.get(index: Int): T =
interpretPointed<IntVarOf<T>>(this.rawValue + index * 4L).value
@JvmName("plus\$Short")
inline operator fun <T : ShortVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Int> CPointer<IntVarOf<T>>.set(index: Int, value: T) {
interpretPointed<IntVarOf<T>>(this.rawValue + index * 4L).value = value
inline operator fun <T : Short> CPointer<ShortVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Short> CPointer<ShortVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Short> CPointer<ShortVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Short> CPointer<ShortVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Int")
operator fun <T : IntVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 4L)
inline operator fun <T : IntVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 4)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Long> CPointer<LongVarOf<T>>.get(index: Int): T =
interpretPointed<LongVarOf<T>>(this.rawValue + index * 8L).value
@JvmName("plus\$Int")
inline operator fun <T : IntVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Long> CPointer<LongVarOf<T>>.set(index: Int, value: T) {
interpretPointed<LongVarOf<T>>(this.rawValue + index * 8L).value = value
inline operator fun <T : Int> CPointer<IntVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Int> CPointer<IntVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Int> CPointer<IntVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Int> CPointer<IntVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Long")
operator fun <T : LongVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 8L)
inline operator fun <T : LongVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 8)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Float> CPointer<FloatVarOf<T>>.get(index: Int): T =
interpretPointed<FloatVarOf<T>>(this.rawValue + index * 4L).value
@JvmName("plus\$Long")
inline operator fun <T : LongVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Float> CPointer<FloatVarOf<T>>.set(index: Int, value: T) {
interpretPointed<FloatVarOf<T>>(this.rawValue + index * 4L).value = value
inline operator fun <T : Long> CPointer<LongVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Long> CPointer<LongVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Long> CPointer<LongVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Long> CPointer<LongVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Float")
operator fun <T : FloatVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 4L)
inline operator fun <T : FloatVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 4)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Double> CPointer<DoubleVarOf<T>>.get(index: Int): T =
interpretPointed<DoubleVarOf<T>>(this.rawValue + index * 8L).value
@JvmName("plus\$Float")
inline operator fun <T : FloatVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : Double> CPointer<DoubleVarOf<T>>.set(index: Int, value: T) {
interpretPointed<DoubleVarOf<T>>(this.rawValue + index * 8L).value = value
inline operator fun <T : Float> CPointer<FloatVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Float> CPointer<FloatVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Float> CPointer<FloatVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Float> CPointer<FloatVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$Double")
operator fun <T : DoubleVar> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * 8L)
inline operator fun <T : DoubleVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * 8)
@JvmName("plus\$Double")
inline operator fun <T : DoubleVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
inline operator fun <T : Double> CPointer<DoubleVarOf<T>>.get(index: Int): T =
(this + index)!!.pointed.value
inline operator fun <T : Double> CPointer<DoubleVarOf<T>>.set(index: Int, value: T) {
(this + index)!!.pointed.value = value
}
inline operator fun <T : Double> CPointer<DoubleVarOf<T>>.get(index: Long): T =
(this + index)!!.pointed.value
inline operator fun <T : Double> CPointer<DoubleVarOf<T>>.set(index: Long, value: T) {
(this + index)!!.pointed.value = value
}
/* Generated by:
#!/bin/bash
function gen {
echo '@Suppress("FINAL_UPPER_BOUND")'
echo "operator fun <T : $1> CPointer<${1}VarOf<T>>.get(index: Int): T ="
echo " interpretPointed<${1}VarOf<T>>(this.rawValue + index * ${2}L).value"
echo "@JvmName(\"plus\\\$$1\")"
echo "inline operator fun <T : ${1}VarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? ="
echo " interpretCPointer(this.rawValue + index * ${2})"
echo
echo '@Suppress("FINAL_UPPER_BOUND")'
echo "operator fun <T : $1> CPointer<${1}VarOf<T>>.set(index: Int, value: T) {"
echo " interpretPointed<${1}VarOf<T>>(this.rawValue + index * ${2}L).value = value"
echo "@JvmName(\"plus\\\$$1\")"
echo "inline operator fun <T : ${1}VarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? ="
echo " this + index.toLong()"
echo
echo "inline operator fun <T : $1> CPointer<${1}VarOf<T>>.get(index: Int): T ="
echo " (this + index)!!.pointed.value"
echo
echo "inline operator fun <T : $1> CPointer<${1}VarOf<T>>.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 <T : ${1}Var> CPointer<T>?.plus(index: Int): CPointer<T>? ="
echo " interpretCPointer(this.rawValue + index * ${2}L)"
echo "inline operator fun <T : $1> CPointer<${1}VarOf<T>>.get(index: Long): T ="
echo " (this + index)!!.pointed.value"
echo
echo "inline operator fun <T : $1> CPointer<${1}VarOf<T>>.set(index: Long, value: T) {"
echo " (this + index)!!.pointed.value = value"
echo '}'
echo
}
@@ -346,19 +346,33 @@ inline operator fun <reified T : CVariable> CPointer<T>.get(index: Long): T {
inline operator fun <reified T : CVariable> CPointer<T>.get(index: Int): T = this.get(index.toLong())
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.get(index: Int): T? =
interpretPointed<CPointerVarOf<T>>(this.rawValue + index * pointerSize.toLong()).value
@Suppress("NOTHING_TO_INLINE")
@JvmName("plus\$CPointer")
inline operator fun <T : CPointerVarOf<*>> CPointer<T>?.plus(index: Long): CPointer<T>? =
interpretCPointer(this.rawValue + index * pointerSize)
@Suppress("FINAL_UPPER_BOUND")
operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.set(index: Int, value: T?) {
interpretPointed<CPointerVarOf<T>>(this.rawValue + index * pointerSize.toLong()).value = value
@Suppress("NOTHING_TO_INLINE")
@JvmName("plus\$CPointer")
inline operator fun <T : CPointerVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
this + index.toLong()
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.get(index: Int): T? =
(this + index)!!.pointed.value
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.set(index: Int, value: T?) {
(this + index)!!.pointed.value = value
}
@Suppress("FINAL_UPPER_BOUND")
@JvmName("plus\$CPointer")
operator fun <T : CPointerVarOf<*>> CPointer<T>?.plus(index: Int): CPointer<T>? =
interpretCPointer(this.rawValue + index * pointerSize.toLong())
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.get(index: Long): T? =
(this + index)!!.pointed.value
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T : CPointer<*>> CPointer<CPointerVarOf<T>>.set(index: Long, value: T?) {
(this + index)!!.pointed.value = value
}
typealias CArrayPointer<T> = CPointer<T>
typealias CArrayPointerVar<T> = CPointerVar<T>
@@ -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
@@ -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<NativeAllocated>(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)
private external fun cfree(ptr: NativePtr)
@@ -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) {
@@ -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
@@ -172,7 +172,7 @@ internal fun RuntimeAware.isObjectType(type: LLVMTypeRef): Boolean {
* Reads [size] bytes contained in this array.
*/
internal fun CArrayPointer<ByteVar>.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)