[Interop][Metadata] Reuse CCall infrastructure to support global structs

This commit is contained in:
Sergey Bogolepov
2020-02-05 19:29:00 +07:00
committed by Sergey Bogolepov
parent fad0b03cff
commit 6713dfbeeb
5 changed files with 29 additions and 3 deletions
@@ -75,6 +75,14 @@ internal class CWrappersGenerator(private val context: StubIrContext) {
return CCalleeWrapper(wrapper)
}
fun generateCGlobalByPointerGetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper {
val wrapperName = generateFunctionWrapperName("${globalDecl.name}_getter")
val returnType = "void*"
val wrapperBody = "return &${globalDecl.name};"
val wrapper = createWrapper(symbolName, wrapperName, returnType, emptyList(), wrapperBody)
return CCalleeWrapper(wrapper)
}
fun generateCGlobalSetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper {
val wrapperName = generateFunctionWrapperName("${globalDecl.name}_setter")
val globalType = globalDecl.type.getStringRepresentation()
@@ -205,7 +205,11 @@ class StubIrBridgeBuilder(
val extra = builderResult.wrapperGenerationComponents.getterToWrapperInfo.getValue(accessor)
val cCallAnnotation = accessor.annotations.firstIsInstanceOrNull<AnnotationStub.CCall.Symbol>()
?: error("external getter for ${extra.global.name} wasn't marked with @CCall")
val wrapper = wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName)
val wrapper = if (extra.passViaPointer) {
wrapperGenerator.generateCGlobalByPointerGetter(extra.global, cCallAnnotation.symbolName)
} else {
wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName)
}
simpleBridgeGenerator.insertNativeBridge(accessor, emptyList(), wrapper.lines)
}
}
@@ -66,7 +66,7 @@ class BridgeGenerationComponentsBuilder {
/**
* Components that are not passed via StubIr but required for generation of wrappers.
*/
class WrapperGenerationInfo(val global: GlobalDecl)
class WrapperGenerationInfo(val global: GlobalDecl, val passViaPointer: Boolean = false)
interface WrapperGenerationComponents {
val getterToWrapperInfo: Map<PropertyAccessor.Getter.ExternalGetter, WrapperGenerationInfo>
@@ -649,7 +649,17 @@ internal class GlobalStubBuilder(
}
is TypeMirror.ByRef -> {
kotlinType = mirror.pointedType
val getter = PropertyAccessor.Getter.InterpretPointed(global.name, kotlinType.toStubIrType())
val getter = when (context.generationMode) {
GenerationMode.SOURCE_CODE -> {
PropertyAccessor.Getter.InterpretPointed(global.name, kotlinType.toStubIrType())
}
GenerationMode.METADATA -> {
val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_getter")
PropertyAccessor.Getter.ExternalGetter(listOf(cCallAnnotation)).also {
context.wrapperComponentsBuilder.getterToWrapperInfo[it] = WrapperGenerationInfo(global, passViaPointer = true)
}
}
}
kind = PropertyStub.Kind.Val(getter)
}
}
@@ -820,6 +820,10 @@ private fun KotlinStubs.mapType(
?: reportUnsupportedType("not a structure or too complex"))
}
type.classOrNull?.isSubtypeOfClass(symbols.nativePointed) == true -> {
TrivialValuePassing(type, CTypes.voidPtr)
}
type.isFunction() -> if (variadic){
reportUnsupportedType("not supported as variadic argument")
} else {