[Interop] Fix handling of unsigned and vector struct fields
This commit is contained in:
committed by
Sergey Bogolepov
parent
9ca6b50d47
commit
3db0cc689c
+1
-1
@@ -763,7 +763,7 @@ private fun KotlinStubs.mapType(type: IrType, retained: Boolean, variadic: Boole
|
|||||||
private fun IrType.isTypeOfNullLiteral(): Boolean = this is IrSimpleType && hasQuestionMark
|
private fun IrType.isTypeOfNullLiteral(): Boolean = this is IrSimpleType && hasQuestionMark
|
||||||
&& classifier.isClassWithFqName(KotlinBuiltIns.FQ_NAMES.nothing)
|
&& classifier.isClassWithFqName(KotlinBuiltIns.FQ_NAMES.nothing)
|
||||||
|
|
||||||
private fun IrType.isVector(): Boolean {
|
internal fun IrType.isVector(): Boolean {
|
||||||
if (this is IrSimpleType && !this.hasQuestionMark) {
|
if (this is IrSimpleType && !this.hasQuestionMark) {
|
||||||
return classifier.isClassWithFqName(KonanFqNames.Vector128.toUnsafe())
|
return classifier.isClassWithFqName(KonanFqNames.Vector128.toUnsafe())
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.backend.common.ir.simpleFunctions
|
|||||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
||||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||||
import org.jetbrains.kotlin.backend.konan.cgen.isCEnumType
|
import org.jetbrains.kotlin.backend.konan.cgen.isCEnumType
|
||||||
|
import org.jetbrains.kotlin.backend.konan.cgen.isVector
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue
|
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.superClasses
|
import org.jetbrains.kotlin.backend.konan.ir.superClasses
|
||||||
@@ -52,6 +53,9 @@ private class InteropCallContext(
|
|||||||
fun IrType.isCPointer(): Boolean = this.classOrNull == symbols.interopCPointer
|
fun IrType.isCPointer(): Boolean = this.classOrNull == symbols.interopCPointer
|
||||||
|
|
||||||
fun IrType.isNativePointed(): Boolean = isSubtypeOfClass(symbols.nativePointed)
|
fun IrType.isNativePointed(): Boolean = isSubtypeOfClass(symbols.nativePointed)
|
||||||
|
|
||||||
|
fun IrType.isStoredInMemoryDirectly(): Boolean =
|
||||||
|
isPrimitiveType() || isUnsigned() || isVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <T> generateInteropCall(
|
private inline fun <T> generateInteropCall(
|
||||||
@@ -84,7 +88,7 @@ private fun InteropCallContext.findMemoryAccessFunction(isRead: Boolean, valueTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.readPrimitiveFromMemory(
|
private fun InteropCallContext.readValueFromMemory(
|
||||||
nativePtr: IrExpression,
|
nativePtr: IrExpression,
|
||||||
returnType: IrType
|
returnType: IrType
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
@@ -99,7 +103,7 @@ private fun InteropCallContext.readPrimitiveFromMemory(
|
|||||||
return castPrimitiveIfNeeded(memRead, returnType)
|
return castPrimitiveIfNeeded(memRead, returnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.writePrimitiveToMemory(
|
private fun InteropCallContext.writeValueToMemory(
|
||||||
nativePtr: IrExpression,
|
nativePtr: IrExpression,
|
||||||
value: IrExpression
|
value: IrExpression
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
@@ -174,13 +178,13 @@ private fun IrType.getCEnumPrimitiveType(): IrType {
|
|||||||
|
|
||||||
private fun InteropCallContext.readEnumValueFromMemory(nativePtr: IrExpression, enumType: IrType): IrExpression {
|
private fun InteropCallContext.readEnumValueFromMemory(nativePtr: IrExpression, enumType: IrType): IrExpression {
|
||||||
val enumPrimitiveType = enumType.getCEnumPrimitiveType()
|
val enumPrimitiveType = enumType.getCEnumPrimitiveType()
|
||||||
val readMemory = readPrimitiveFromMemory(nativePtr, enumPrimitiveType)
|
val readMemory = readValueFromMemory(nativePtr, enumPrimitiveType)
|
||||||
return convertIntegralToEnum(readMemory, enumType)
|
return convertIntegralToEnum(readMemory, enumType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.writeEnumValueToMemory(nativePtr: IrExpression, value: IrExpression): IrExpression {
|
private fun InteropCallContext.writeEnumValueToMemory(nativePtr: IrExpression, value: IrExpression): IrExpression {
|
||||||
val valueToWrite = convertEnumToIntegral(value)
|
val valueToWrite = convertEnumToIntegral(value)
|
||||||
return writePrimitiveToMemory(nativePtr, valueToWrite)
|
return writeValueToMemory(nativePtr, valueToWrite)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.convertCPointerToNativePtr(cPointer: IrExpression): IrExpression {
|
private fun InteropCallContext.convertCPointerToNativePtr(cPointer: IrExpression): IrExpression {
|
||||||
@@ -195,7 +199,7 @@ private fun InteropCallContext.writePointerToMemory(nativePtr: IrExpression, val
|
|||||||
value.type.isCPointer() -> convertCPointerToNativePtr(value)
|
value.type.isCPointer() -> convertCPointerToNativePtr(value)
|
||||||
else -> error("Unsupported pointer type")
|
else -> error("Unsupported pointer type")
|
||||||
}
|
}
|
||||||
return writePrimitiveToMemory(nativePtr, valueToWrite)
|
return writeValueToMemory(nativePtr, valueToWrite)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.calculateFieldPointer(receiver: IrExpression, offset: Long): IrExpression {
|
private fun InteropCallContext.calculateFieldPointer(receiver: IrExpression, offset: Long): IrExpression {
|
||||||
@@ -213,7 +217,7 @@ private fun InteropCallContext.calculateFieldPointer(receiver: IrExpression, off
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun InteropCallContext.readPointerFromMemory(nativePtr: IrExpression): IrExpression {
|
private fun InteropCallContext.readPointerFromMemory(nativePtr: IrExpression): IrExpression {
|
||||||
val readMemory = readPrimitiveFromMemory(nativePtr, symbols.nativePtrType)
|
val readMemory = readValueFromMemory(nativePtr, symbols.nativePtrType)
|
||||||
return builder.irCall(symbols.interopInterpretCPointer).also {
|
return builder.irCall(symbols.interopInterpretCPointer).also {
|
||||||
it.putValueArgument(0, readMemory)
|
it.putValueArgument(0, readMemory)
|
||||||
}
|
}
|
||||||
@@ -268,7 +272,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
|
|||||||
val type = accessor.returnType
|
val type = accessor.returnType
|
||||||
when {
|
when {
|
||||||
type.isCEnumType() -> readEnumValueFromMemory(fieldPointer, type)
|
type.isCEnumType() -> readEnumValueFromMemory(fieldPointer, type)
|
||||||
type.isPrimitiveType() -> readPrimitiveFromMemory(fieldPointer, type)
|
type.isStoredInMemoryDirectly() -> readValueFromMemory(fieldPointer, type)
|
||||||
type.isCPointer() -> readPointerFromMemory(fieldPointer)
|
type.isCPointer() -> readPointerFromMemory(fieldPointer)
|
||||||
type.isNativePointed() -> readPointed(fieldPointer)
|
type.isNativePointed() -> readPointed(fieldPointer)
|
||||||
else -> error("Cannot get field type: ${type.getClass()?.name}")
|
else -> error("Cannot get field type: ${type.getClass()?.name}")
|
||||||
@@ -279,7 +283,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
|
|||||||
val type = accessor.valueParameters[0].type
|
val type = accessor.valueParameters[0].type
|
||||||
when {
|
when {
|
||||||
type.isCEnumType() -> writeEnumValueToMemory(fieldPointer, value)
|
type.isCEnumType() -> writeEnumValueToMemory(fieldPointer, value)
|
||||||
type.isPrimitiveType() -> writePrimitiveToMemory(fieldPointer, value)
|
type.isStoredInMemoryDirectly() -> writeValueToMemory(fieldPointer, value)
|
||||||
type.isCPointer() -> writePointerToMemory(fieldPointer, value)
|
type.isCPointer() -> writePointerToMemory(fieldPointer, value)
|
||||||
else -> error("Cannot set field of type ${type.getClass()?.name}")
|
else -> error("Cannot set field of type ${type.getClass()?.name}")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user