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