[StubIr] Support for structs
This commit is contained in:
committed by
Sergey Bogolepov
parent
60bb7312d9
commit
e0117fd297
+9
-2
@@ -199,8 +199,13 @@ sealed class AnnotationStub(val classifier: Classifier) {
|
||||
class Symbol(val symbolName: String) : CCall(cCallClassifier)
|
||||
}
|
||||
|
||||
class CStruct(val struct: String) :
|
||||
AnnotationStub(Classifier.topLevel(cinteropInternalPackage, "CStruct"))
|
||||
class CStruct(val struct: String) : AnnotationStub(cStructClassifier) {
|
||||
class MemberAt(val offset: Long) : AnnotationStub(cStructClassifier.nested("MemberAt"))
|
||||
|
||||
class BitField(val offset: Long, val size: Int) : AnnotationStub(cStructClassifier.nested("BitField"))
|
||||
|
||||
class VarType(val size: Long, val align: Int) : AnnotationStub(cStructClassifier.nested("VarType"))
|
||||
}
|
||||
|
||||
class CNaturalStruct(val members: List<StructMember>) :
|
||||
AnnotationStub(Classifier.topLevel(cinteropPackage, "CNaturalStruct"))
|
||||
@@ -220,6 +225,8 @@ sealed class AnnotationStub(val classifier: Classifier) {
|
||||
|
||||
private companion object {
|
||||
val cCallClassifier = Classifier.topLevel(cinteropInternalPackage, "CCall")
|
||||
|
||||
val cStructClassifier = Classifier.topLevel(cinteropInternalPackage, "CStruct")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
-12
@@ -84,20 +84,37 @@ internal class StructStubBuilder(
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
val kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.ArrayMemberAt(offset))
|
||||
val getter = when (context.generationMode) {
|
||||
GenerationMode.SOURCE_CODE -> PropertyAccessor.Getter.ArrayMemberAt(offset)
|
||||
GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset)))
|
||||
}
|
||||
val kind = PropertyStub.Kind.Val(getter)
|
||||
// TODO: Should receiver be added?
|
||||
PropertyStub(field.name, type.toStubIrType(), kind, annotations = annotations, origin = origin)
|
||||
} else {
|
||||
val pointedType = fieldRefType.pointedType.toStubIrType()
|
||||
val pointedTypeArgument = TypeArgumentStub(pointedType)
|
||||
if (fieldRefType is TypeMirror.ByValue) {
|
||||
val kind = PropertyStub.Kind.Var(
|
||||
PropertyAccessor.Getter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument), hasValueAccessor = true),
|
||||
PropertyAccessor.Setter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument))
|
||||
)
|
||||
val getter: PropertyAccessor.Getter
|
||||
val setter: PropertyAccessor.Setter
|
||||
when (context.generationMode) {
|
||||
GenerationMode.SOURCE_CODE -> {
|
||||
getter = PropertyAccessor.Getter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument), hasValueAccessor = true)
|
||||
setter = PropertyAccessor.Setter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument))
|
||||
}
|
||||
GenerationMode.METADATA -> {
|
||||
getter = PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset)))
|
||||
setter = PropertyAccessor.Setter.ExternalSetter(listOf(AnnotationStub.CStruct.MemberAt(offset)))
|
||||
}
|
||||
}
|
||||
val kind = PropertyStub.Kind.Var(getter, setter)
|
||||
PropertyStub(field.name, fieldRefType.argType.toStubIrType(), kind, origin = origin)
|
||||
} else {
|
||||
val kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.MemberAt(offset, hasValueAccessor = false))
|
||||
val accessor = when (context.generationMode) {
|
||||
GenerationMode.SOURCE_CODE -> PropertyAccessor.Getter.MemberAt(offset, hasValueAccessor = false)
|
||||
GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset)))
|
||||
}
|
||||
val kind = PropertyStub.Kind.Val(accessor)
|
||||
PropertyStub(field.name, pointedType, kind, origin = origin)
|
||||
}
|
||||
}
|
||||
@@ -111,11 +128,20 @@ internal class StructStubBuilder(
|
||||
val typeInfo = typeMirror.info
|
||||
val kotlinType = typeMirror.argType
|
||||
val signed = field.type.isIntegerTypeSigned()
|
||||
val readBits = PropertyAccessor.Getter.ReadBits(field.offset, field.size, signed)
|
||||
val writeBits = PropertyAccessor.Setter.WriteBits(field.offset, field.size)
|
||||
context.bridgeComponentsBuilder.getterToBridgeInfo[readBits] = BridgeGenerationInfo("", typeInfo)
|
||||
context.bridgeComponentsBuilder.setterToBridgeInfo[writeBits] = BridgeGenerationInfo("", typeInfo)
|
||||
val kind = PropertyStub.Kind.Var(readBits, writeBits)
|
||||
val kind = when (context.generationMode) {
|
||||
GenerationMode.SOURCE_CODE -> {
|
||||
val readBits = PropertyAccessor.Getter.ReadBits(field.offset, field.size, signed)
|
||||
val writeBits = PropertyAccessor.Setter.WriteBits(field.offset, field.size)
|
||||
context.bridgeComponentsBuilder.getterToBridgeInfo[readBits] = BridgeGenerationInfo("", typeInfo)
|
||||
context.bridgeComponentsBuilder.setterToBridgeInfo[writeBits] = BridgeGenerationInfo("", typeInfo)
|
||||
PropertyStub.Kind.Var(readBits, writeBits)
|
||||
}
|
||||
GenerationMode.METADATA -> {
|
||||
val readBits = PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.BitField(field.offset, field.size)))
|
||||
val writeBits = PropertyAccessor.Setter.ExternalSetter(listOf(AnnotationStub.CStruct.BitField(field.offset, field.size)))
|
||||
PropertyStub.Kind.Var(readBits, writeBits)
|
||||
}
|
||||
}
|
||||
PropertyStub(field.name, kotlinType.toStubIrType(), kind, origin = StubOrigin.StructMember(field))
|
||||
}
|
||||
|
||||
@@ -135,7 +161,10 @@ internal class StructStubBuilder(
|
||||
val typeSize = listOf(IntegralConstantStub(def.size, 4, true), IntegralConstantStub(def.align.toLong(), 4, true))
|
||||
val companionSuperInit = SuperClassInit(companionSuper, typeSize)
|
||||
val companionClassifier = classifier.nested("Companion")
|
||||
val companion = ClassStub.Companion(companionClassifier, emptyList(), companionSuperInit)
|
||||
val annotation = AnnotationStub.CStruct.VarType(def.size, def.align).takeIf {
|
||||
context.generationMode == GenerationMode.METADATA
|
||||
}
|
||||
val companion = ClassStub.Companion(companionClassifier, superClassInit = companionSuperInit, annotations = listOfNotNull(annotation))
|
||||
|
||||
return listOf(ClassStub.Simple(
|
||||
classifier,
|
||||
|
||||
+11
@@ -390,6 +390,17 @@ private class MappingExtensions(
|
||||
is AnnotationStub.CEnumVarTypeSize -> mapOfNotNull(
|
||||
("size" to KmAnnotationArgument.IntValue(size))
|
||||
)
|
||||
is AnnotationStub.CStruct.MemberAt -> mapOfNotNull(
|
||||
("offset" to KmAnnotationArgument.LongValue(offset))
|
||||
)
|
||||
is AnnotationStub.CStruct.BitField -> mapOfNotNull(
|
||||
("offset" to KmAnnotationArgument.LongValue(offset)),
|
||||
("size" to KmAnnotationArgument.IntValue(size))
|
||||
)
|
||||
is AnnotationStub.CStruct.VarType -> mapOfNotNull(
|
||||
("size" to KmAnnotationArgument.LongValue(size)),
|
||||
("align" to KmAnnotationArgument.IntValue(align))
|
||||
)
|
||||
}
|
||||
return KmAnnotation(classifier.fqNameSerialized, args)
|
||||
}
|
||||
|
||||
+4
-1
@@ -497,7 +497,10 @@ class StubIrTextEmitter(
|
||||
"ReplaceWith(${annotationStub.replaceWith.quoteAsKotlinLiteral()}), " +
|
||||
"DeprecationLevel.ERROR)"
|
||||
is AnnotationStub.CEnumEntryAlias,
|
||||
is AnnotationStub.CEnumVarTypeSize ->
|
||||
is AnnotationStub.CEnumVarTypeSize,
|
||||
is AnnotationStub.CStruct.MemberAt,
|
||||
is AnnotationStub.CStruct.BitField,
|
||||
is AnnotationStub.CStruct.VarType ->
|
||||
error("${annotationStub.classifier.fqName} annotation is unsupported in textual mode")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user