Interop, backend: refactor and reorder interop lowering
* Do not break type compatibility when lowering interop intrinsics. * Place interop lowering before callable reference lowering. * Add other improvements to interop implementation.
This commit is contained in:
committed by
SvyatoslavScherbina
parent
6c627a0b55
commit
3411ce2e8c
@@ -15,7 +15,7 @@ data class StableObjPtr private constructor(val value: COpaquePointer) {
|
||||
*/
|
||||
fun create(any: Any) = fromValue(newGlobalRef(any))
|
||||
|
||||
private fun fromValue(value: NativePtr) = fromValue(CPointer.create(value))
|
||||
private fun fromValue(value: NativePtr) = fromValue(interpretCPointer(value)!!)
|
||||
|
||||
/**
|
||||
* Creates [StableObjPtr] from given raw value.
|
||||
@@ -219,7 +219,7 @@ private fun ffiCreateCif(returnType: ffi_type, paramTypes: List<ffi_type>): ffi_
|
||||
|
||||
private fun ffiFunImpl0(ffiCif: Long, ret: Long, args: Long, userData: Any) {
|
||||
ffiFunImpl(interpretPointed(ffiCif),
|
||||
CPointer.create(ret),
|
||||
interpretCPointer(ret)!!,
|
||||
interpretPointed(args),
|
||||
userData as UserData)
|
||||
}
|
||||
|
||||
@@ -11,21 +11,30 @@ val nativeNullPtr: NativePtr = 0L
|
||||
inline fun <reified T : CVariable> typeOf() = T::class.companionObjectInstance as CVariable.Type
|
||||
|
||||
/**
|
||||
* Returns interpretation of entity with given pointer.
|
||||
* Returns interpretation of entity with given pointer, or `null` if it is null.
|
||||
*
|
||||
* @param T must not be abstract
|
||||
*/
|
||||
inline fun <reified T : NativePointed> interpretPointed(ptr: NativePtr): T {
|
||||
return ensuringNotNull(ptr) {
|
||||
inline fun <reified T : NativePointed> interpretNullablePointed(ptr: NativePtr): T? {
|
||||
if (ptr == nativeNullPtr) {
|
||||
return null
|
||||
} else {
|
||||
val kClass = T::class
|
||||
val primaryConstructor = kClass.primaryConstructor
|
||||
if (primaryConstructor == null) {
|
||||
throw IllegalArgumentException("${kClass.simpleName} doesn't have a constructor")
|
||||
}
|
||||
(primaryConstructor as (NativePtr) -> T)(ptr)
|
||||
return (primaryConstructor as (NativePtr) -> T)(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : CPointed> interpretCPointer(rawValue: NativePtr) =
|
||||
if (rawValue == nativeNullPtr) {
|
||||
null
|
||||
} else {
|
||||
CPointer<T>(rawValue)
|
||||
}
|
||||
|
||||
inline fun <reified T : CAdaptedFunctionType<*>> CAdaptedFunctionType.Companion.getInstanceOf(): T =
|
||||
T::class.objectInstance!!
|
||||
|
||||
|
||||
@@ -12,40 +12,14 @@ interface NativePointed {
|
||||
|
||||
// `null` value of `NativePointed?` is mapped to `nativeNullPtr`.
|
||||
val NativePointed?.rawPtr: NativePtr
|
||||
get() = this?.rawPtr ?: nativeNullPtr
|
||||
get() = if (this != null) this.rawPtr else nativeNullPtr
|
||||
|
||||
/**
|
||||
* Returns interpretation of entity with given pointer, or `null` if it is null.
|
||||
* Returns interpretation of entity with given pointer.
|
||||
*
|
||||
* @param T must not be abstract
|
||||
*/
|
||||
inline fun <reified T : NativePointed> interpretNullablePointed(ptr: NativePtr): T? {
|
||||
return ifNotNull(ptr) {
|
||||
interpretPointed<T>(it)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the function to the pointer if it is not null, otherwise returns `null`.
|
||||
*/
|
||||
inline fun <T> ifNotNull(ptr: NativePtr, function: (NativePtr)->T): T? {
|
||||
return if (ptr == nativeNullPtr) {
|
||||
null
|
||||
} else {
|
||||
function(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the function to the pointer ensuring that it is not null.
|
||||
*/
|
||||
inline fun <T> ensuringNotNull(ptr: NativePtr, function: (NativePtr)->T): T {
|
||||
if (ptr == nativeNullPtr) {
|
||||
throw IllegalArgumentException()
|
||||
} else {
|
||||
return function(ptr)
|
||||
}
|
||||
}
|
||||
inline fun <reified T : NativePointed> interpretPointed(ptr: NativePtr): T = interpretNullablePointed<T>(ptr)!!
|
||||
|
||||
/**
|
||||
* Changes the interpretation of the pointed data or code.
|
||||
@@ -60,16 +34,7 @@ interface CPointed : NativePointed
|
||||
/**
|
||||
* C pointer.
|
||||
*/
|
||||
class CPointer<T : CPointed> private constructor(val rawValue: NativePtr) {
|
||||
companion object {
|
||||
fun <T : CPointed> create(rawValue: NativePtr) = ensuringNotNull(rawValue) {
|
||||
CPointer<T>(rawValue)
|
||||
}
|
||||
|
||||
fun <T : CPointed> createNullable(rawValue: NativePtr) = ifNotNull(rawValue) {
|
||||
CPointer<T>(it)
|
||||
}
|
||||
}
|
||||
class CPointer<T : CPointed> internal constructor(val rawValue: NativePtr) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
@@ -90,7 +55,7 @@ class CPointer<T : CPointed> private constructor(val rawValue: NativePtr) {
|
||||
* Returns the pointer to this data or code.
|
||||
*/
|
||||
val <T : CPointed> T.ptr: CPointer<T>
|
||||
get() = CPointer.create(this.rawPtr)
|
||||
get() = interpretCPointer(this.rawPtr)!!
|
||||
|
||||
/**
|
||||
* Returns the corresponding [CPointed].
|
||||
@@ -104,7 +69,7 @@ inline val <reified T : CPointed> CPointer<T>.pointed: T
|
||||
val CPointer<*>?.rawValue: NativePtr
|
||||
get() = this?.rawValue ?: nativeNullPtr
|
||||
|
||||
fun <T : CPointed> CPointer<*>.reinterpret(): CPointer<T> = CPointer.create(this.rawValue)
|
||||
fun <T : CPointed> CPointer<*>.reinterpret(): CPointer<T> = interpretCPointer(this.rawValue)!!
|
||||
|
||||
/**
|
||||
* The [CPointed] without any specified interpretation.
|
||||
@@ -251,7 +216,7 @@ typealias CPointerVar<T> = CPointerVarWithValueMappedTo<CPointer<T>>
|
||||
* The value of this variable.
|
||||
*/
|
||||
inline var <reified P : CPointer<*>> CPointerVarWithValueMappedTo<P>.value: P?
|
||||
get() = CPointer.createNullable<CPointed>(nativeMemUtils.getNativePtr(this)) as P?
|
||||
get() = interpretCPointer<CPointed>(nativeMemUtils.getNativePtr(this)) as P?
|
||||
set(value) = nativeMemUtils.putNativePtr(this, value.rawValue)
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,10 +151,10 @@ fun <T : CPointed> NativePlacement.allocPointerTo() = alloc<CPointerVar<T>>()
|
||||
/**
|
||||
* The zero-terminated string.
|
||||
*/
|
||||
class CString private constructor(override val rawPtr: NativePtr) : CPointed {
|
||||
class CString(override val rawPtr: NativePtr) : CPointed {
|
||||
|
||||
companion object {
|
||||
fun fromArray(array: CArray<CInt8Var>) = CString(array.rawPtr)
|
||||
fun fromArray(array: CArray<CInt8Var>) = array.reinterpret<CString>()
|
||||
}
|
||||
|
||||
fun length(): Int {
|
||||
|
||||
@@ -51,7 +51,7 @@ object nativeMemUtils {
|
||||
if (ptr == nativeNullPtr) {
|
||||
throw OutOfMemoryError("unable to allocate native memory")
|
||||
}
|
||||
return NativeAllocated(ptr)
|
||||
return interpretPointed<NativeAllocated>(ptr)
|
||||
}
|
||||
|
||||
fun free(mem: NativePointed) {
|
||||
|
||||
@@ -14,11 +14,17 @@ inline val nativeNullPtr: NativePtr
|
||||
fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument")
|
||||
|
||||
/**
|
||||
* Returns interpretation of entity with given pointer.
|
||||
* Returns interpretation of entity with given pointer, or `null` if it is null.
|
||||
*
|
||||
* @param T must not be abstract
|
||||
*/
|
||||
@Intrinsic external fun <T : NativePointed> interpretPointed(ptr: NativePtr): T
|
||||
@Intrinsic external fun <T : NativePointed> interpretNullablePointed(ptr: NativePtr): T?
|
||||
|
||||
@Intrinsic external fun <T : CPointed> interpretCPointer(rawValue: NativePtr): CPointer<T>?
|
||||
|
||||
@Intrinsic external fun NativePointed.getRawPointer(): NativePtr
|
||||
|
||||
@Intrinsic external fun CPointer<*>.getRawValue(): NativePtr
|
||||
|
||||
inline fun <reified T : CAdaptedFunctionType<*>> CAdaptedFunctionType.Companion.getInstanceOf(): T =
|
||||
TODO("CAdaptedFunctionType.getInstanceOf")
|
||||
|
||||
Reference in New Issue
Block a user