[StubIr][Metadata] Add support for array members of structs
This commit is contained in:
committed by
Sergey Bogolepov
parent
91fb5eca76
commit
4e1482750b
@@ -10,6 +10,10 @@ annotation class CStruct(val spelling: String) {
|
||||
)
|
||||
annotation class MemberAt(val offset: Long)
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(AnnotationTarget.PROPERTY_GETTER)
|
||||
annotation class ArrayMemberAt(val offset: Long)
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(
|
||||
AnnotationTarget.PROPERTY_GETTER,
|
||||
|
||||
+2
@@ -202,6 +202,8 @@ sealed class AnnotationStub(val classifier: Classifier) {
|
||||
class CStruct(val struct: String) : AnnotationStub(cStructClassifier) {
|
||||
class MemberAt(val offset: Long) : AnnotationStub(cStructClassifier.nested("MemberAt"))
|
||||
|
||||
class ArrayMemberAt(val offset: Long) : AnnotationStub(cStructClassifier.nested("ArrayMemberAt"))
|
||||
|
||||
class BitField(val offset: Long, val size: Int) : AnnotationStub(cStructClassifier.nested("BitField"))
|
||||
|
||||
class VarType(val size: Long, val align: Int) : AnnotationStub(cStructClassifier.nested("VarType"))
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ internal class StructStubBuilder(
|
||||
}
|
||||
val getter = when (context.generationMode) {
|
||||
GenerationMode.SOURCE_CODE -> PropertyAccessor.Getter.ArrayMemberAt(offset)
|
||||
GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset)))
|
||||
GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.ArrayMemberAt(offset)))
|
||||
}
|
||||
val kind = PropertyStub.Kind.Val(getter)
|
||||
// TODO: Should receiver be added?
|
||||
|
||||
+3
@@ -393,6 +393,9 @@ private class MappingExtensions(
|
||||
is AnnotationStub.CStruct.MemberAt -> mapOfNotNull(
|
||||
("offset" to KmAnnotationArgument.LongValue(offset))
|
||||
)
|
||||
is AnnotationStub.CStruct.ArrayMemberAt -> mapOfNotNull(
|
||||
("offset" to KmAnnotationArgument.LongValue(offset))
|
||||
)
|
||||
is AnnotationStub.CStruct.BitField -> mapOfNotNull(
|
||||
("offset" to KmAnnotationArgument.LongValue(offset)),
|
||||
("size" to KmAnnotationArgument.IntValue(size))
|
||||
|
||||
+1
@@ -499,6 +499,7 @@ class StubIrTextEmitter(
|
||||
is AnnotationStub.CEnumEntryAlias,
|
||||
is AnnotationStub.CEnumVarTypeSize,
|
||||
is AnnotationStub.CStruct.MemberAt,
|
||||
is AnnotationStub.CStruct.ArrayMemberAt,
|
||||
is AnnotationStub.CStruct.BitField,
|
||||
is AnnotationStub.CStruct.VarType ->
|
||||
error("${annotationStub.classifier.fqName} annotation is unsupported in textual mode")
|
||||
|
||||
+6
@@ -185,6 +185,11 @@ private object PredefinedTypesHandler {
|
||||
return AbbreviatedType(objCClass, KotlinTypes.objCObjectMeta, emptyList(), nullable)
|
||||
}
|
||||
|
||||
private fun expandCArrayPointer(typeArguments: List<TypeArgument>, nullable: Boolean): AbbreviatedType {
|
||||
val cPointer = ClassifierStubType(KotlinTypes.cPointer, typeArguments)
|
||||
return AbbreviatedType(cPointer, KotlinTypes.cArrayPointer, typeArguments, nullable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return [ClassifierStubType] if [classifier] is a typealias from [kotlinx.cinterop] package.
|
||||
*/
|
||||
@@ -195,6 +200,7 @@ private object PredefinedTypesHandler {
|
||||
KotlinTypes.cOpaquePointerVar.classifier -> expandCOpaquePointerVar(nullable)
|
||||
KotlinTypes.cPointerVar -> expandCPointerVar(typeArguments, nullable)
|
||||
KotlinTypes.objCObjectMeta -> expandObjCObjectMeta(typeArguments, nullable)
|
||||
KotlinTypes.cArrayPointer -> expandCArrayPointer(typeArguments, nullable)
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ object RuntimeNames {
|
||||
val exportTypeInfoAnnotation = FqName("kotlin.native.internal.ExportTypeInfo")
|
||||
val cCall = FqName("kotlinx.cinterop.internal.CCall")
|
||||
val cStructMemberAt = FqName("kotlinx.cinterop.internal.CStruct.MemberAt")
|
||||
val cStructArrayMemberAt = FqName("kotlinx.cinterop.internal.CStruct.ArrayMemberAt")
|
||||
val cStructBitField = FqName("kotlinx.cinterop.internal.CStruct.BitField")
|
||||
val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod")
|
||||
val objCMethodImp = FqName("kotlinx.cinterop.ObjCMethodImp")
|
||||
|
||||
+15
@@ -39,6 +39,9 @@ private fun isEnumVarValueAccessor(function: IrFunction, symbols: KonanSymbols):
|
||||
private fun isMemberAtAccessor(function: IrFunction): Boolean =
|
||||
function.hasAnnotation(RuntimeNames.cStructMemberAt)
|
||||
|
||||
private fun isArrayMemberAtAccessor(function: IrFunction): Boolean =
|
||||
function.hasAnnotation(RuntimeNames.cStructArrayMemberAt)
|
||||
|
||||
private fun isBitFieldAccessor(function: IrFunction): Boolean =
|
||||
function.hasAnnotation(RuntimeNames.cStructBitField)
|
||||
|
||||
@@ -238,6 +241,8 @@ internal fun tryGenerateInteropMemberAccess(
|
||||
generateInteropCall(symbols, builder) { generateMemberAtAccess(callSite) }
|
||||
isBitFieldAccessor(callSite.symbol.owner) ->
|
||||
generateInteropCall(symbols, builder) { generateBitFieldAccess(callSite) }
|
||||
isArrayMemberAtAccessor(callSite.symbol.owner) ->
|
||||
generateInteropCall(symbols, builder) { generateArrayMemberAtAccess(callSite) }
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -283,6 +288,16 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
|
||||
}
|
||||
}
|
||||
|
||||
private fun InteropCallContext.generateArrayMemberAtAccess(callSite: IrCall): IrExpression {
|
||||
val accessor = callSite.symbol.owner
|
||||
val memberAt = accessor.getAnnotation(RuntimeNames.cStructArrayMemberAt)!!
|
||||
val offset = (memberAt.getValueArgument(0) as IrConst<Long>).value
|
||||
val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset)
|
||||
return builder.irCall(symbols.interopInterpretCPointer).also {
|
||||
it.putValueArgument(0, fieldPointer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun InteropCallContext.writeBits(
|
||||
base: IrExpression,
|
||||
offset: Long,
|
||||
|
||||
Reference in New Issue
Block a user